summaryrefslogtreecommitdiffhomepage
path: root/talpid-core
diff options
context:
space:
mode:
authorMarkus Pettersson <markus.pettersson@mullvad.net>2023-10-24 15:36:39 +0200
committerMarkus Pettersson <markus.pettersson@mullvad.net>2023-11-07 19:34:14 +0100
commit288a29de4d1ba2c0771afa37b64c39f727b13706 (patch)
treee45bb05a57db74d2ddfa3954fd9e8c3e899b771c /talpid-core
parent77d41767571f6e1b0d3f096c67410932dd1db90d (diff)
downloadmullvadvpn-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.rs24
-rw-r--r--talpid-core/src/firewall/macos.rs30
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>> {