From e24b58a6694ef60501c26628545a0cf6791daaa9 Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Tue, 6 May 2025 15:01:03 +0200 Subject: [PATCH 1/2] namespace nft tables by interface name --- src/enterprise/firewall/linux/mod.rs | 13 ++++--- src/enterprise/firewall/linux/netfilter.rs | 45 ++++++++++++++-------- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/enterprise/firewall/linux/mod.rs b/src/enterprise/firewall/linux/mod.rs index 12f7e142..3a43d046 100644 --- a/src/enterprise/firewall/linux/mod.rs +++ b/src/enterprise/firewall/linux/mod.rs @@ -79,11 +79,12 @@ impl FirewallManagementApi for FirewallApi { ) -> Result<(), FirewallError> { debug!("Initializing firewall, VPN interface: {}", self.ifname); if let Some(batch) = &mut self.batch { - drop_table(batch)?; - init_firewall(default_policy, priority, batch).expect("Failed to setup chains"); + drop_table(batch, &self.ifname)?; + init_firewall(default_policy, priority, batch, &self.ifname) + .expect("Failed to setup chains"); debug!("Allowing all established traffic"); ignore_unrelated_traffic(batch, &self.ifname)?; - allow_established_traffic(batch)?; + allow_established_traffic(batch, &self.ifname)?; debug!("Allowed all established traffic"); debug!("Initialized firewall"); Ok(()) @@ -96,7 +97,7 @@ impl FirewallManagementApi for FirewallApi { fn cleanup(&mut self) -> Result<(), FirewallError> { debug!("Cleaning up all previous firewall rules, if any"); if let Some(batch) = &mut self.batch { - drop_table(batch)?; + drop_table(batch, &self.ifname)?; } else { return Err(FirewallError::TransactionNotStarted); } @@ -108,7 +109,7 @@ impl FirewallManagementApi for FirewallApi { fn set_firewall_default_policy(&mut self, policy: Policy) -> Result<(), FirewallError> { debug!("Setting default firewall policy to: {policy:?}"); if let Some(batch) = &mut self.batch { - set_default_policy(policy, batch)?; + set_default_policy(policy, batch, &self.ifname)?; } else { return Err(FirewallError::TransactionNotStarted); } @@ -218,7 +219,7 @@ impl FirewallManagementApi for FirewallApi { } } - apply_filter_rules(rules, batch)?; + apply_filter_rules(rules, batch, &self.ifname)?; debug!( "Applied firewall rules for Defguard ACL rule ID: {}", diff --git a/src/enterprise/firewall/linux/netfilter.rs b/src/enterprise/firewall/linux/netfilter.rs index 840c0879..995393a4 100644 --- a/src/enterprise/firewall/linux/netfilter.rs +++ b/src/enterprise/firewall/linux/netfilter.rs @@ -21,7 +21,7 @@ use crate::enterprise::firewall::FirewallError; const FILTER_TABLE: &str = "filter"; const NAT_TABLE: &str = "nat"; -const DEFGUARD_TABLE: &str = "DEFGUARD"; +const DEFGUARD_TABLE: &str = "DEFGUARD-{IFNAME}"; const POSTROUTING_CHAIN: &str = "POSTROUTING"; const FORWARD_CHAIN: &str = "FORWARD"; const ANON_SET_NAME: &str = "__set%d"; @@ -563,8 +563,9 @@ pub(crate) fn init_firewall( initial_policy: Option, defguard_fwd_chain_priority: Option, batch: &mut Batch, + ifname: &str, ) -> Result<(), FirewallError> { - let table = Tables::Defguard(ProtoFamily::Inet).to_table(); + let table = Tables::Defguard(ProtoFamily::Inet).to_table(ifname); batch.add(&table, nftnl::MsgType::Add); batch.add(&table, nftnl::MsgType::Del); @@ -582,16 +583,20 @@ pub(crate) fn init_firewall( Ok(()) } -pub(crate) fn drop_table(batch: &mut Batch) -> Result<(), FirewallError> { - let table = Tables::Defguard(ProtoFamily::Inet).to_table(); +pub(crate) fn drop_table(batch: &mut Batch, ifname: &str) -> Result<(), FirewallError> { + let table = Tables::Defguard(ProtoFamily::Inet).to_table(ifname); batch.add(&table, nftnl::MsgType::Add); batch.add(&table, nftnl::MsgType::Del); Ok(()) } -pub(crate) fn drop_chain(chain: &Chains, batch: &mut Batch) -> Result<(), FirewallError> { - let table = Tables::Defguard(ProtoFamily::Inet).to_table(); +pub(crate) fn drop_chain( + chain: &Chains, + batch: &mut Batch, + ifname: &str, +) -> Result<(), FirewallError> { + let table = Tables::Defguard(ProtoFamily::Inet).to_table(ifname); let chain = chain.to_chain(&table); batch.add(&chain, nftnl::MsgType::Add); batch.add(&chain, nftnl::MsgType::Del); @@ -601,11 +606,11 @@ pub(crate) fn drop_chain(chain: &Chains, batch: &mut Batch) -> Result<(), Firewa /// Applies masquerade on the specified interface for the outgoing packets pub(crate) fn set_masq( - _ifname: &str, + ifname: &str, enabled: bool, batch: &mut Batch, ) -> Result<(), FirewallError> { - let table = Tables::Defguard(ProtoFamily::Inet).to_table(); + let table = Tables::Defguard(ProtoFamily::Inet).to_table(ifname); batch.add(&table, nftnl::MsgType::Add); drop_chain(&Chains::Postrouting, batch)?; @@ -633,8 +638,12 @@ pub(crate) fn set_masq( Ok(()) } -pub(crate) fn set_default_policy(policy: Policy, batch: &mut Batch) -> Result<(), FirewallError> { - let table = Tables::Defguard(ProtoFamily::Inet).to_table(); +pub(crate) fn set_default_policy( + policy: Policy, + batch: &mut Batch, + ifname: &str, +) -> Result<(), FirewallError> { + let table = Tables::Defguard(ProtoFamily::Inet).to_table(ifname); batch.add(&table, nftnl::MsgType::Add); let mut forward_chain = Chains::Forward.to_chain(&table); @@ -648,8 +657,11 @@ pub(crate) fn set_default_policy(policy: Policy, batch: &mut Batch) -> Result<() Ok(()) } -pub(crate) fn allow_established_traffic(batch: &mut Batch) -> Result<(), FirewallError> { - let table = Tables::Defguard(ProtoFamily::Inet).to_table(); +pub(crate) fn allow_established_traffic( + batch: &mut Batch, + ifname: &str, +) -> Result<(), FirewallError> { + let table = Tables::Defguard(ProtoFamily::Inet).to_table(ifname); batch.add(&table, nftnl::MsgType::Add); let forward_chain = Chains::Forward.to_chain(&table); @@ -672,7 +684,7 @@ pub(crate) fn ignore_unrelated_traffic( batch: &mut Batch, ifname: &str, ) -> Result<(), FirewallError> { - let table = Tables::Defguard(ProtoFamily::Inet).to_table(); + let table = Tables::Defguard(ProtoFamily::Inet).to_table(ifname); batch.add(&table, nftnl::MsgType::Add); let forward_chain = Chains::Forward.to_chain(&table); @@ -699,7 +711,7 @@ pub enum Tables { } impl Tables { - fn to_table(&self) -> Table { + fn to_table(&self, ifname: &str) -> Table { match self { Self::Filter(family) => Table::new( &CString::new(FILTER_TABLE) @@ -712,7 +724,7 @@ impl Tables { *family, ), Self::Defguard(family) => Table::new( - &CString::new(DEFGUARD_TABLE) + &CString::new(DEFGUARD_TABLE.replace("{IFNAME}", ifname)) .expect("Failed to create CString from DEFGUARD_TABLE constant."), *family, ), @@ -745,8 +757,9 @@ impl Chains { pub(crate) fn apply_filter_rules( rules: Vec, batch: &mut Batch, + ifname: &str, ) -> Result<(), FirewallError> { - let table = Tables::Defguard(ProtoFamily::Inet).to_table(); + let table = Tables::Defguard(ProtoFamily::Inet).to_table(ifname); batch.add(&table, nftnl::MsgType::Add); let forward_chain = Chains::Forward.to_chain(&table); From ea13ad04b4547e2ea0f35a5719534eec26044ead Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Tue, 6 May 2025 15:07:22 +0200 Subject: [PATCH 2/2] fix --- src/enterprise/firewall/linux/netfilter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/enterprise/firewall/linux/netfilter.rs b/src/enterprise/firewall/linux/netfilter.rs index 995393a4..e0cff456 100644 --- a/src/enterprise/firewall/linux/netfilter.rs +++ b/src/enterprise/firewall/linux/netfilter.rs @@ -613,7 +613,7 @@ pub(crate) fn set_masq( let table = Tables::Defguard(ProtoFamily::Inet).to_table(ifname); batch.add(&table, nftnl::MsgType::Add); - drop_chain(&Chains::Postrouting, batch)?; + drop_chain(&Chains::Postrouting, batch, ifname)?; let mut nat_chain = Chains::Postrouting.to_chain(&table); nat_chain.set_hook(nftnl::Hook::PostRouting, POSTROUTING_PRIORITY);