summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2024-05-02 10:56:30 +0200
committerAlbin <albin@mullvad.net>2024-05-08 14:55:02 +0200
commit64393a6c5b09738c7e5c70bd4bc40d63169618a6 (patch)
treefa3dc4d75edc042414f24aff7c19710df0a8ed23
parent44dcda5625ddbbc2bceb4689de28d837f6526ced (diff)
downloadmullvadvpn-64393a6c5b09738c7e5c70bd4bc40d63169618a6.tar.xz
mullvadvpn-64393a6c5b09738c7e5c70bd4bc40d63169618a6.zip
Set dummy DNS servers in blocking states
This is a fix for DNS leaks in blocking states due to an underlying OS bug where DNS queries leak when no DNS server is configured. Lockdown mode ("Block connections without VPN") would also not help in this case. More information on this issue: https://issuetracker.google.com/issues/337961996
-rw-r--r--talpid-tunnel/src/tun_provider/android/mod.rs41
1 files changed, 30 insertions, 11 deletions
diff --git a/talpid-tunnel/src/tun_provider/android/mod.rs b/talpid-tunnel/src/tun_provider/android/mod.rs
index 187dd3b4f5..baccd3f3fc 100644
--- a/talpid-tunnel/src/tun_provider/android/mod.rs
+++ b/talpid-tunnel/src/tun_provider/android/mod.rs
@@ -56,6 +56,7 @@ pub struct AndroidTunProvider {
object: GlobalRef,
last_tun_config: TunConfig,
allow_lan: bool,
+ blocking: bool,
custom_dns_servers: Option<Vec<IpAddr>>,
allowed_lan_networks: Vec<IpNetwork>,
}
@@ -82,6 +83,7 @@ impl AndroidTunProvider {
object: context.vpn_service,
last_tun_config: TunConfig::default(),
allow_lan,
+ blocking: false,
custom_dns_servers,
allowed_lan_networks,
}
@@ -105,8 +107,15 @@ impl AndroidTunProvider {
Ok(())
}
+ /// Retrieve a tunnel device with the provided configuration. Custom DNS and LAN routes are
+ /// appended to the provided config.
+ pub fn get_tun(&mut self, mut config: TunConfig) -> Result<VpnServiceTun, Error> {
+ self.prepare_tun_config(&mut config, false);
+ self.get_tun_inner(config)
+ }
+
/// Retrieve a tunnel device with the provided configuration.
- pub fn get_tun(&mut self, config: TunConfig) -> Result<VpnServiceTun, Error> {
+ fn get_tun_inner(&mut self, config: TunConfig) -> Result<VpnServiceTun, Error> {
let tun_fd = self.get_tun_fd(config.clone())?;
self.last_tun_config = config;
@@ -122,15 +131,15 @@ impl AndroidTunProvider {
})
}
- /// Open a tunnel device that routes everything but custom DNS, and
- /// (potentially) LAN routes via the tunnel device.
+ /// Open a tunnel device that routes everything but (potentially) LAN routes via the tunnel
+ /// device.
///
/// Will open a new tunnel if there is already an active tunnel. The previous tunnel will be
/// closed.
pub fn create_blocking_tun(&mut self) -> Result<(), Error> {
let mut config = TunConfig::default();
- self.prepare_tun_config(&mut config);
- let _ = self.get_tun(config)?;
+ self.prepare_tun_config(&mut config, true);
+ let _ = self.get_tun_inner(config)?;
Ok(())
}
@@ -176,9 +185,7 @@ impl AndroidTunProvider {
}
}
- fn get_tun_fd(&mut self, mut config: TunConfig) -> Result<RawFd, Error> {
- self.prepare_tun_config(&mut config);
-
+ fn get_tun_fd(&mut self, config: TunConfig) -> Result<RawFd, Error> {
let env = self.env()?;
let java_config = config.into_java(&env);
@@ -198,7 +205,7 @@ impl AndroidTunProvider {
fn recreate_tun_if_open(&mut self) -> Result<(), Error> {
let mut actual_config = self.last_tun_config.clone();
- self.prepare_tun_config(&mut actual_config);
+ self.prepare_tun_config(&mut actual_config, self.blocking);
let env = self.env()?;
let java_config = actual_config.into_java(&env);
@@ -216,9 +223,13 @@ impl AndroidTunProvider {
}
}
- fn prepare_tun_config(&self, config: &mut TunConfig) {
+ fn prepare_tun_config(&mut self, config: &mut TunConfig, blocking: bool) {
+ self.blocking = blocking;
self.prepare_tun_config_for_allow_lan(config);
- self.prepare_tun_config_for_custom_dns(config);
+ if !blocking {
+ self.prepare_tun_config_for_custom_dns(config);
+ }
+ maybe_set_dummy_dns_servers(config);
}
fn prepare_tun_config_for_allow_lan(&self, config: &mut TunConfig) {
@@ -324,6 +335,14 @@ impl AndroidTunProvider {
}
}
+/// Add dummy servers if no DNS servers are set. Android may sometimes leak DNS otherwise.
+fn maybe_set_dummy_dns_servers(config: &mut TunConfig) {
+ if !config.dns_servers.is_empty() {
+ return;
+ }
+ config.dns_servers = vec!["192.0.2.1".parse().unwrap()];
+}
+
/// Handle to a tunnel device on Android.
pub struct VpnServiceTun {
tunnel: RawFd,