summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2020-02-14 13:31:06 +0100
committerDavid Lönnhager <david.l@mullvad.net>2020-06-02 10:05:01 +0200
commit39c1a12c5c7f234fe32f397d93d60eb49234cfa1 (patch)
tree9bbbe8a6708a2fb9505c052aac5cf5d8be03d7cd
parentff83525821524fc1f25725236929b1483260e10a (diff)
downloadmullvadvpn-39c1a12c5c7f234fe32f397d93d60eb49234cfa1.tar.xz
mullvadvpn-39c1a12c5c7f234fe32f397d93d60eb49234cfa1.zip
Update firewall to accept packets originating with split tunnel cgroup
-rw-r--r--talpid-core/src/firewall/linux.rs38
-rw-r--r--talpid-core/src/split.rs2
2 files changed, 38 insertions, 2 deletions
diff --git a/talpid-core/src/firewall/linux.rs b/talpid-core/src/firewall/linux.rs
index 4bf52d62d8..52327091ec 100644
--- a/talpid-core/src/firewall/linux.rs
+++ b/talpid-core/src/firewall/linux.rs
@@ -1,5 +1,5 @@
use super::{FirewallArguments, FirewallPolicy, FirewallT};
-use crate::tunnel;
+use crate::{split, tunnel};
use ipnetwork::IpNetwork;
use lazy_static::lazy_static;
use libc;
@@ -16,6 +16,10 @@ use std::{
};
use talpid_types::net::{Endpoint, TransportProtocol};
+/// Priority for rules that tag split tunneling packets. Equals NF_IP_PRI_MANGLE.
+const MANGLE_CHAIN_PRIORITY: i32 = libc::NF_IP_PRI_MANGLE;
+const SPLIT_TUNNEL_MARK: i32 = 0xf41;
+
pub type Result<T> = std::result::Result<T, Error>;
/// Errors that can happen when interacting with Linux netfilter.
@@ -57,6 +61,7 @@ lazy_static! {
static ref TABLE_NAME: CString = CString::new("mullvad").unwrap();
static ref IN_CHAIN_NAME: CString = CString::new("input").unwrap();
static ref OUT_CHAIN_NAME: CString = CString::new("output").unwrap();
+ static ref MANGLE_CHAIN_NAME: CString = CString::new("mangle").unwrap();
/// Allows controlling whether firewall rules should have packet counters or not from an env
/// variable. Useful for debugging the rules.
@@ -187,6 +192,7 @@ struct PolicyBatch<'a> {
batch: Batch,
in_chain: Chain<'a>,
out_chain: Chain<'a>,
+ mangle_chain: Chain<'a>,
}
impl<'a> PolicyBatch<'a> {
@@ -208,10 +214,17 @@ impl<'a> PolicyBatch<'a> {
batch.add(&out_chain, nftnl::MsgType::Add);
batch.add(&in_chain, nftnl::MsgType::Add);
+ let mut mangle_chain = Chain::new(&*MANGLE_CHAIN_NAME, table);
+ mangle_chain.set_hook(nftnl::Hook::Out, MANGLE_CHAIN_PRIORITY);
+ mangle_chain.set_type(nftnl::ChainType::Route);
+ mangle_chain.set_policy(nftnl::Policy::Accept);
+ batch.add(&mangle_chain, nftnl::MsgType::Add);
+
PolicyBatch {
batch,
in_chain,
out_chain,
+ mangle_chain,
}
}
@@ -219,12 +232,35 @@ impl<'a> PolicyBatch<'a> {
/// policy.
pub fn finalize(mut self, policy: &FirewallPolicy) -> Result<FinalizedBatch> {
self.add_loopback_rules()?;
+ self.add_split_tunneling_rules();
self.add_dhcp_client_rules();
self.add_policy_specific_rules(policy)?;
Ok(self.batch.finalize())
}
+ fn add_split_tunneling_rules(&mut self) {
+ let mut rule = Rule::new(&self.mangle_chain);
+ rule.add_expr(&nft_expr!(meta cgroup));
+ rule.add_expr(&nft_expr!(cmp == split::NETCLS_CLASSID));
+ rule.add_expr(&nft_expr!(immediate data SPLIT_TUNNEL_MARK));
+ rule.add_expr(&nft_expr!(ct mark set));
+ rule.add_expr(&nft_expr!(meta mark set));
+ self.batch.add(&rule, nftnl::MsgType::Add);
+
+ let mut rule = Rule::new(&self.in_chain);
+ rule.add_expr(&nft_expr!(ct mark));
+ rule.add_expr(&nft_expr!(cmp == SPLIT_TUNNEL_MARK));
+ add_verdict(&mut rule, &Verdict::Accept);
+ self.batch.add(&rule, nftnl::MsgType::Add);
+
+ let mut rule = Rule::new(&self.out_chain);
+ rule.add_expr(&nft_expr!(meta mark));
+ rule.add_expr(&nft_expr!(cmp == SPLIT_TUNNEL_MARK));
+ add_verdict(&mut rule, &Verdict::Accept);
+ self.batch.add(&rule, nftnl::MsgType::Add);
+ }
+
fn add_loopback_rules(&mut self) -> Result<()> {
const LOOPBACK_IFACE_NAME: &str = "lo";
self.batch.add(
diff --git a/talpid-core/src/split.rs b/talpid-core/src/split.rs
index d4b279a701..71b9926ec3 100644
--- a/talpid-core/src/split.rs
+++ b/talpid-core/src/split.rs
@@ -6,7 +6,7 @@ use std::{
const NETCLS_DIR: &str = "/sys/fs/cgroup/net_cls/";
/// Identifies packets coming from the cgroup.
-const NETCLS_CLASSID: u32 = 0x4d9f41;
+pub const NETCLS_CLASSID: u32 = 0x4d9f41;
const CGROUP_NAME: &str = "mullvad-exclusions";
/// Errors related to split tunneling.