diff options
| author | Markus Pettersson <markus.pettersson@mullvad.net> | 2023-10-24 15:36:39 +0200 |
|---|---|---|
| committer | Markus Pettersson <markus.pettersson@mullvad.net> | 2023-11-07 19:34:14 +0100 |
| commit | 288a29de4d1ba2c0771afa37b64c39f727b13706 (patch) | |
| tree | e45bb05a57db74d2ddfa3954fd9e8c3e899b771c /talpid-core | |
| parent | 77d41767571f6e1b0d3f096c67410932dd1db90d (diff) | |
| download | mullvadvpn-288a29de4d1ba2c0771afa37b64c39f727b13706.tar.xz mullvadvpn-288a29de4d1ba2c0771afa37b64c39f727b13706.zip | |
Configure firewall rules to allow proxy clients
The default setting will (always) be to only allow processes with
root-privilege to send/receive traffic from an allowed endpoint.
This change is only supposed to be used with the local SOCKS5 api access
method.
Diffstat (limited to 'talpid-core')
| -rw-r--r-- | talpid-core/src/firewall/linux.rs | 24 | ||||
| -rw-r--r-- | talpid-core/src/firewall/macos.rs | 30 |
2 files changed, 31 insertions, 23 deletions
diff --git a/talpid-core/src/firewall/linux.rs b/talpid-core/src/firewall/linux.rs index 1b74fb30bd..a74aa1ce4a 100644 --- a/talpid-core/src/firewall/linux.rs +++ b/talpid-core/src/firewall/linux.rs @@ -14,7 +14,7 @@ use std::{ fs, io, net::{IpAddr, Ipv4Addr}, }; -use talpid_types::net::{AllowedTunnelTraffic, Endpoint, TransportProtocol}; +use talpid_types::net::{AllowedEndpoint, AllowedTunnelTraffic, 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; @@ -519,7 +519,7 @@ impl<'a> PolicyBatch<'a> { allowed_tunnel_traffic, } => { self.add_allow_tunnel_endpoint_rules(peer_endpoint, fwmark); - self.add_allow_endpoint_rules(&allowed_endpoint.endpoint); + self.add_allow_endpoint_rules(allowed_endpoint); // Important to block DNS after allow relay rule (so the relay can operate // over port 53) but before allow LAN (so DNS does not leak to the LAN) @@ -568,7 +568,7 @@ impl<'a> PolicyBatch<'a> { allowed_endpoint, } => { if let Some(endpoint) = allowed_endpoint { - self.add_allow_endpoint_rules(&endpoint.endpoint); + self.add_allow_endpoint_rules(endpoint); } // Important to drop DNS before allowing LAN (to stop DNS leaking to the LAN) @@ -628,24 +628,28 @@ impl<'a> PolicyBatch<'a> { /// Adds firewall rules allow traffic to flow to the API. Allows the app to reach the API in /// blocked states. - fn add_allow_endpoint_rules(&mut self, endpoint: &Endpoint) { + fn add_allow_endpoint_rules(&mut self, endpoint: &AllowedEndpoint) { let mut in_rule = Rule::new(&self.in_chain); - check_endpoint(&mut in_rule, End::Src, endpoint); + check_endpoint(&mut in_rule, End::Src, &endpoint.endpoint); let allowed_states = nftnl::expr::ct::States::ESTABLISHED.bits(); in_rule.add_expr(&nft_expr!(ct state)); in_rule.add_expr(&nft_expr!(bitwise mask allowed_states, xor 0u32)); in_rule.add_expr(&nft_expr!(cmp != 0u32)); - in_rule.add_expr(&nft_expr!(meta skuid)); - in_rule.add_expr(&nft_expr!(cmp == super::ROOT_UID)); + if !endpoint.clients.allow_all() { + in_rule.add_expr(&nft_expr!(meta skuid)); + in_rule.add_expr(&nft_expr!(cmp == super::ROOT_UID)); + } add_verdict(&mut in_rule, &Verdict::Accept); self.batch.add(&in_rule, nftnl::MsgType::Add); let mut out_rule = Rule::new(&self.out_chain); - check_endpoint(&mut out_rule, End::Dst, endpoint); - out_rule.add_expr(&nft_expr!(meta skuid)); - out_rule.add_expr(&nft_expr!(cmp == super::ROOT_UID)); + check_endpoint(&mut out_rule, End::Dst, &endpoint.endpoint); + if !endpoint.clients.allow_all() { + out_rule.add_expr(&nft_expr!(meta skuid)); + out_rule.add_expr(&nft_expr!(cmp == super::ROOT_UID)); + } add_verdict(&mut out_rule, &Verdict::Accept); self.batch.add(&out_rule, nftnl::MsgType::Add); diff --git a/talpid-core/src/firewall/macos.rs b/talpid-core/src/firewall/macos.rs index 4f95309890..54f72a79c2 100644 --- a/talpid-core/src/firewall/macos.rs +++ b/talpid-core/src/firewall/macos.rs @@ -6,7 +6,7 @@ use std::{ net::{IpAddr, Ipv4Addr}, }; use subslice::SubsliceExt; -use talpid_types::net::{self, AllowedTunnelTraffic}; +use talpid_types::net::{self, AllowedEndpoint, AllowedTunnelTraffic}; pub use pfctl::Error; @@ -122,7 +122,7 @@ impl Firewall { allowed_tunnel_traffic, } => { let mut rules = vec![self.get_allow_relay_rule(*peer_endpoint)?]; - rules.push(self.get_allowed_endpoint_rule(allowed_endpoint.endpoint)?); + rules.push(self.get_allowed_endpoint_rule(allowed_endpoint)?); // Important to block DNS after allow relay rule (so the relay can operate // over port 53) but before allow LAN (so DNS does not leak to the LAN) @@ -175,7 +175,7 @@ impl Firewall { } => { let mut rules = Vec::new(); if let Some(allowed_endpoint) = allowed_endpoint { - rules.push(self.get_allowed_endpoint_rule(allowed_endpoint.endpoint)?); + rules.push(self.get_allowed_endpoint_rule(allowed_endpoint)?); } if *allow_lan { @@ -287,22 +287,26 @@ impl Firewall { .build() } - /// Produces a rule that allows traffic to flow to the API. Allows the app to reach the API in - /// blocked states. + /// Produces a rule that allows traffic to flow to the API. Allows the app (or other apps if configured) + /// to reach the API in blocked states. fn get_allowed_endpoint_rule( &self, - allowed_endpoint: net::Endpoint, + allowed_endpoint: &AllowedEndpoint, ) -> Result<pfctl::FilterRule> { - let pfctl_proto = as_pfctl_proto(allowed_endpoint.protocol); + let pfctl_proto = as_pfctl_proto(allowed_endpoint.endpoint.protocol); - self.create_rule_builder(FilterRuleAction::Pass) - .direction(pfctl::Direction::Out) - .to(allowed_endpoint.address) + let mut rule = self.create_rule_builder(FilterRuleAction::Pass); + rule.direction(pfctl::Direction::Out) + .to(allowed_endpoint.endpoint.address) .proto(pfctl_proto) .keep_state(pfctl::StatePolicy::Keep) - .user(Uid::from(super::ROOT_UID)) - .quick(true) - .build() + .quick(true); + + if !allowed_endpoint.clients.allow_all() { + rule.user(Uid::from(super::ROOT_UID)).build()?; + } + + rule.build() } fn get_block_dns_rules(&self) -> Result<Vec<pfctl::FilterRule>> { |
