Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify nft check to check if binary exists before setting up nftables #802

Merged
merged 1 commit into from
Jul 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 30 additions & 12 deletions althea_kernel_interface/src/counter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,10 @@ add zxcv 1234:5678:9801:2345:6789:0123:4567:8902,wg0 packets 123456789 bytes 987

impl dyn KernelInterface {
pub fn init_counter(&self, target: &FilterTarget) -> Result<(), Error> {
if self.get_kernel_is_v4()? {
if self.does_nftables_exist() {
info!("Trying to init a counter!");
self.nft_init_counters(target.set_name(), target.chain(), target.nft_interface())?;
} else {
self.run_command(
"ipset",
&[
Expand Down Expand Up @@ -165,9 +168,6 @@ impl dyn KernelInterface {
&format!("dst,{}", target.interface()),
],
)?;
} else {
info!("Trying to init a counter!");
self.nft_init_counters(target.set_name(), target.chain(), target.nft_interface())?;
}

Ok(())
Expand Down Expand Up @@ -235,7 +235,9 @@ impl dyn KernelInterface {
&self,
target: &FilterTarget,
) -> Result<HashMap<(IpAddr, String), u64>, Error> {
if self.get_kernel_is_v4()? {
if self.does_nftables_exist() {
self.parse_nft_set_counters(target.set_name())
} else {
self.run_command(
"ipset",
&[
Expand Down Expand Up @@ -264,8 +266,6 @@ impl dyn KernelInterface {

self.run_command("ipset", &["destroy", &format!("tmp_{}", target.set_name())])?;
res
} else {
self.parse_nft_set_counters(target.set_name())
}
}
}
Expand All @@ -282,7 +282,7 @@ fn test_init_counter() {

KI.set_mock(Box::new(move |program, args| {
counter += 1;
if KI.get_kernel_is_v4().unwrap() {
if KI.get_kernel_is_v4()? {
match counter {
1 => {
assert_eq!(program, "ipset");
Expand Down Expand Up @@ -338,6 +338,15 @@ fn test_init_counter() {
} else {
match counter {
1 => {
assert_eq!(program, "nft");
assert_eq!(args, &["-v"]);
Ok(Output {
stdout: b"nftables v1.0.1 (Fearless Fosdick #3)".to_vec(),
stderr: b"".to_vec(),
status: ExitStatus::from_raw(0),
})
}
2 => {
assert_eq!(program, "nft");
assert_eq!(args, &["list", "set", "inet", "fw4", "rita_input"]);

Expand All @@ -347,7 +356,7 @@ fn test_init_counter() {
status: ExitStatus::from_raw(0),
})
}
2 => {
3 => {
assert_eq!(program, "nft");
assert_eq!(
args,
Expand Down Expand Up @@ -377,7 +386,7 @@ fn test_init_counter() {
status: ExitStatus::from_raw(0),
})
}
3 => {
4 => {
assert_eq!(program, "nft");
assert_eq!(
args,
Expand Down Expand Up @@ -422,7 +431,7 @@ fn test_read_counters() {

KI.set_mock(Box::new(move |program, args| {
counter += 1;
if KI.get_kernel_is_v4().unwrap() {
if KI.get_kernel_is_v4()? {
match counter {
1 => {
assert_eq!(program, "ipset");
Expand Down Expand Up @@ -478,6 +487,15 @@ fn test_read_counters() {
} else {
match counter {
1 => {
assert_eq!(program, "nft");
assert_eq!(args, &["-v"]);
Ok(Output {
stdout: b"nftables v1.0.1 (Fearless Fosdick #3)".to_vec(),
stderr: b"".to_vec(),
status: ExitStatus::from_raw(0),
})
}
2 => {
assert_eq!(program, "nft");
assert_eq!(args, &["list", "set", "inet", "fw4", "rita_input"]);
Ok(Output {
Expand All @@ -489,7 +507,7 @@ fn test_read_counters() {
status: ExitStatus::from_raw(0),
})
}
2 => {
3 => {
assert_eq!(program, "nft");
assert_eq!(args, &["flush", "set", "inet", "fw4", "rita_input"]);
Ok(Output {
Expand Down
10 changes: 5 additions & 5 deletions althea_kernel_interface/src/exit_client_tunnel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,9 @@ impl dyn KernelInterface {
/// same rules. It may be advisable in the future to split them up into
/// individual nat entires for each option
pub fn create_client_nat_rules(&self) -> Result<(), Error> {
let is_v4 = self.get_kernel_is_v4()?;
let use_iptables = !self.does_nftables_exist();

if is_v4 {
if use_iptables {
self.add_iptables_rule(
"iptables",
&[
Expand All @@ -234,7 +234,7 @@ impl dyn KernelInterface {
}

// Set mtu
if is_v4 {
if use_iptables {
self.add_iptables_rule(
"iptables",
&[
Expand Down Expand Up @@ -275,7 +275,7 @@ impl dyn KernelInterface {
/// blocks the client nat by inserting a blocker in the start of the special lan forwarding
/// table created by openwrt.
pub fn block_client_nat(&self) -> Result<(), Error> {
if self.get_kernel_is_v4()? {
if !self.does_nftables_exist() {
self.add_iptables_rule("iptables", &["-I", "zone_lan_forward", "-j", "REJECT"])?;
} else {
self.insert_reject_rule()?;
Expand All @@ -285,7 +285,7 @@ impl dyn KernelInterface {

/// Removes the block created by block_client_nat() will fail if not run after that command
pub fn restore_client_nat(&self) -> Result<(), Error> {
if self.get_kernel_is_v4()? {
if !self.does_nftables_exist() {
self.add_iptables_rule("iptables", &["-D", "zone_lan_forward", "-j", "REJECT"])?;
} else {
self.delete_reject_rule()?;
Expand Down
4 changes: 2 additions & 2 deletions althea_kernel_interface/src/exit_server_tunnel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ impl dyn KernelInterface {
external_v6: Option<(IpAddr, u8)>,
) -> Result<(), Error> {
// nat masquerade on exit
if self.get_kernel_is_v4()? {
if !self.does_nftables_exist() {
self.add_iptables_rule(
"iptables",
&[
Expand All @@ -248,7 +248,7 @@ impl dyn KernelInterface {
}

// Add v4 and v6 forward rules wg_exit <-> ex_nic
if self.get_kernel_is_v4()? {
if !self.does_nftables_exist() {
// v4 wg_exit -> ex_nic
self.add_iptables_rule(
"iptables",
Expand Down
21 changes: 21 additions & 0 deletions althea_kernel_interface/src/netfilter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@ use crate::KernelInterface;
use crate::KernelInterfaceError;

impl dyn KernelInterface {
pub fn does_nftables_exist(&self) -> bool {
let output = match self.run_command("nft", &["-v"]) {
Ok(out) => out,
Err(e) => {
error!("Run command is failing with {}", e);
// Assume there is no nftables
return false;
}
};

let stdout = match String::from_utf8(output.stdout) {
Ok(a) => a,
Err(e) => {
error!("Cannot parse stdout with {}", e);
return false;
}
};

stdout.contains("nftables")
}

fn create_fwd_rule(&self) -> Result<(), KernelInterfaceError> {
self.run_command(
"nft",
Expand Down
Loading