summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2020-02-12 14:56:16 +0100
committerLinus Färnstrand <linus@mullvad.net>2020-02-12 16:45:30 +0100
commit92b795974fab5394fb57ebf858d27c32ee75dcaf (patch)
tree9d781df13c970624d3aa95a912cbfe59b4432b0c
parente93dfcbdea7f69673027ba64453ae47c0a40daa2 (diff)
downloadmullvadvpn-92b795974fab5394fb57ebf858d27c32ee75dcaf.tar.xz
mullvadvpn-92b795974fab5394fb57ebf858d27c32ee75dcaf.zip
Fix DNS leaks on macOS
-rw-r--r--talpid-core/src/firewall/macos.rs46
1 files changed, 29 insertions, 17 deletions
diff --git a/talpid-core/src/firewall/macos.rs b/talpid-core/src/firewall/macos.rs
index acf9b68cc6..41898f36cd 100644
--- a/talpid-core/src/firewall/macos.rs
+++ b/talpid-core/src/firewall/macos.rs
@@ -94,6 +94,9 @@ impl Firewall {
let mut rules = vec![self.get_allow_relay_rule(peer_endpoint)?];
rules.extend(self.get_allow_pingable_hosts(&pingable_hosts)?);
if allow_lan {
+ // 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)
+ rules.append(&mut self.get_block_dns_rules()?);
rules.append(&mut self.get_allow_lan_rules()?);
}
Ok(rules)
@@ -144,24 +147,12 @@ impl Firewall {
rules.push(v6_dns_rule_udp);
}
- let block_tcp_dns_rule = self
- .create_rule_builder(FilterRuleAction::Drop)
- .direction(pfctl::Direction::Out)
- .quick(true)
- .proto(pfctl::Proto::Tcp)
- .to(pfctl::Port::from(53))
- .build()?;
- rules.push(block_tcp_dns_rule);
- let block_udp_dns_rule = self
- .create_rule_builder(FilterRuleAction::Drop)
- .direction(pfctl::Direction::Out)
- .quick(true)
- .proto(pfctl::Proto::Udp)
- .to(pfctl::Port::from(53))
- .build()?;
-
- rules.push(block_udp_dns_rule);
rules.push(self.get_allow_relay_rule(peer_endpoint)?);
+
+ // Important to block DNS *before* we allow the tunnel and allow LAN. So DNS
+ // can't leak to the wrong IPs in the tunnel or on the LAN.
+ rules.append(&mut self.get_block_dns_rules()?);
+
rules.push(self.get_allow_tunnel_rule(tunnel.interface.as_str())?);
if allow_lan {
@@ -173,6 +164,8 @@ impl Firewall {
FirewallPolicy::Blocked { allow_lan } => {
let mut rules = Vec::new();
if allow_lan {
+ // Important to block DNS before allow LAN (so DNS does not leak to the LAN)
+ rules.append(&mut self.get_block_dns_rules()?);
rules.append(&mut self.get_allow_lan_rules()?);
}
Ok(rules)
@@ -194,6 +187,25 @@ impl Firewall {
.build()?)
}
+ fn get_block_dns_rules(&self) -> Result<Vec<pfctl::FilterRule>> {
+ let block_tcp_dns_rule = self
+ .create_rule_builder(FilterRuleAction::Drop)
+ .direction(pfctl::Direction::Out)
+ .quick(true)
+ .proto(pfctl::Proto::Tcp)
+ .to(pfctl::Port::from(53))
+ .build()?;
+ let block_udp_dns_rule = self
+ .create_rule_builder(FilterRuleAction::Drop)
+ .direction(pfctl::Direction::Out)
+ .quick(true)
+ .proto(pfctl::Proto::Udp)
+ .to(pfctl::Port::from(53))
+ .build()?;
+
+ Ok(vec![block_tcp_dns_rule, block_udp_dns_rule])
+ }
+
fn get_allow_pingable_hosts(
&self,
pingable_hosts: &[IpAddr],