summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEmīls <emils@mullvad.net>2021-03-05 14:24:25 +0000
committerEmīls <emils@mullvad.net>2021-03-05 14:24:25 +0000
commit0ef60858616494b9cc1c27de45798698063cc8fc (patch)
treeb9cdee864e85d217929e34c0c4ccd4f93dbf522b
parent60f6ba4b0edd120012877afc1ca1ff6122be18fe (diff)
parent5d4ff8ed0673735404c4fbc8de7f353c62e5a67b (diff)
downloadmullvadvpn-0ef60858616494b9cc1c27de45798698063cc8fc.tar.xz
mullvadvpn-0ef60858616494b9cc1c27de45798698063cc8fc.zip
Merge branch 'linux-fix-rfp-rules'
-rw-r--r--CHANGELOG.md1
-rw-r--r--talpid-core/src/firewall/linux.rs17
2 files changed, 18 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 99548b21df..70bad09ff5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -62,6 +62,7 @@ Line wrap the file at 100 chars. Th
#### Linux
- Fix DNS issues where NM would overwrite Mullvad tunnel's DNS config in systemd-resolved.
+- Fix issues with hosts where the firewall is doing reverse path filtering.
#### Android
- Fix input area sometimes disappearing when returning to the Login screen.
diff --git a/talpid-core/src/firewall/linux.rs b/talpid-core/src/firewall/linux.rs
index 04bd00777d..86007b5843 100644
--- a/talpid-core/src/firewall/linux.rs
+++ b/talpid-core/src/firewall/linux.rs
@@ -18,6 +18,7 @@ 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 PREROUTING_CHAIN_PRIORITY: i32 = -1000;
pub type Result<T> = std::result::Result<T, Error>;
@@ -60,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 ALLOW_TUNNEL_TRAFFIC_CHAIN_NAME: CString = CString::new("allow_relay_prerouting").unwrap();
/// We need two separate tables for compatibility with older kernels (holds true for kernel
/// version 4.19 but not 5.6), where the base filter type may not be `nftnl::ChainType::Route`
@@ -209,6 +211,7 @@ struct PolicyBatch<'a> {
batch: Batch,
in_chain: Chain<'a>,
out_chain: Chain<'a>,
+ allow_tunnel_chain: Chain<'a>,
mangle_chain_v4: Chain<'a>,
mangle_chain_v6: Chain<'a>,
nat_chain_v4: Chain<'a>,
@@ -220,6 +223,10 @@ impl<'a> PolicyBatch<'a> {
/// table and chains.
pub fn new(tables: &'a FirewallTables) -> Self {
let mut batch = Batch::new();
+ let mut allow_tunnel_chain = Chain::new(&*ALLOW_TUNNEL_TRAFFIC_CHAIN_NAME, &tables.main);
+ allow_tunnel_chain.set_hook(nftnl::Hook::PreRouting, PREROUTING_CHAIN_PRIORITY);
+ allow_tunnel_chain.set_type(nftnl::ChainType::Filter);
+
let mut out_chain = Chain::new(&*OUT_CHAIN_NAME, &tables.main);
let mut in_chain = Chain::new(&*IN_CHAIN_NAME, &tables.main);
out_chain.set_hook(nftnl::Hook::Out, 0);
@@ -228,9 +235,11 @@ impl<'a> PolicyBatch<'a> {
in_chain.set_policy(nftnl::Policy::Drop);
Self::flush_table(&mut batch, &tables.main);
+ batch.add(&allow_tunnel_chain, nftnl::MsgType::Add);
batch.add(&out_chain, nftnl::MsgType::Add);
batch.add(&in_chain, nftnl::MsgType::Add);
+
Self::flush_table(&mut batch, &tables.mangle_v4);
Self::flush_table(&mut batch, &tables.mangle_v6);
@@ -262,6 +271,7 @@ impl<'a> PolicyBatch<'a> {
batch,
in_chain,
out_chain,
+ allow_tunnel_chain,
mangle_chain_v4,
mangle_chain_v6,
nat_chain_v4,
@@ -590,6 +600,13 @@ impl<'a> PolicyBatch<'a> {
}
fn add_allow_tunnel_endpoint_rules(&mut self, endpoint: &Endpoint, use_fwmark: bool) {
+ let mut prerouting_rule = Rule::new(&self.allow_tunnel_chain);
+ check_endpoint(&mut prerouting_rule, End::Src, endpoint);
+ prerouting_rule.add_expr(&nft_expr!(immediate data crate::linux::TUNNEL_FW_MARK));
+ prerouting_rule.add_expr(&nft_expr!(meta mark set));
+
+ self.batch.add(&prerouting_rule, nftnl::MsgType::Add);
+
let mut in_rule = Rule::new(&self.in_chain);
check_endpoint(&mut in_rule, End::Src, endpoint);