summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEmīls <emils@mullvad.net>2019-11-22 15:14:08 +0000
committerEmīls <emils@mullvad.net>2019-11-22 15:14:08 +0000
commit37261f0d5c214b926053329bf24d8e7bd1efbfcb (patch)
tree6de4f1929d9d5f79bb0863c1e64e5badd320564d
parentae70854bfdcc70871276348de523e44455689531 (diff)
parent92d931cbbc62d6b20c6e0b44f8cb41f50f09b9a8 (diff)
downloadmullvadvpn-37261f0d5c214b926053329bf24d8e7bd1efbfcb.tar.xz
mullvadvpn-37261f0d5c214b926053329bf24d8e7bd1efbfcb.zip
Merge branch 'resolvconf-check-dnsmasq'
-rw-r--r--CHANGELOG.md3
-rw-r--r--talpid-core/src/dns/linux/resolvconf.rs45
2 files changed, 48 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 05b84dfcaa..91891d3716 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -43,9 +43,12 @@ Line wrap the file at 100 chars. Th
- Upgrade libsodium from 1.0.17 to 1.0.18.
- Upgrade NDIS 6 TAP driver from 9.21.2 to 9.24.2.
+
### Fixed
#### Linux
- Improved stability on Linux by using the routing netlink socket in it's own thread.
+- When trying to use `resolvconf` for managing DNS, the daemon will check if
+ `dnsmasq` is running and misconfigured.
#### Windows
- Detect removal of the OpenVPN TAP adapter on reconnection attempts.
diff --git a/talpid-core/src/dns/linux/resolvconf.rs b/talpid-core/src/dns/linux/resolvconf.rs
index 537db43b10..3a32eaf406 100644
--- a/talpid-core/src/dns/linux/resolvconf.rs
+++ b/talpid-core/src/dns/linux/resolvconf.rs
@@ -5,6 +5,7 @@ use std::{
net::IpAddr,
path::{Path, PathBuf},
};
+
use which::which;
pub type Result<T> = std::result::Result<T, Error>;
@@ -25,6 +26,9 @@ pub enum Error {
#[error(display = "Using 'resolvconf' to delete a record failed")]
DeleteRecordError,
+
+ #[error(display = "Detected dnsmasq is runing and misconfigured")]
+ DnsmasqMisconfigurationError,
}
pub struct Resolvconf {
@@ -38,6 +42,11 @@ impl Resolvconf {
if Self::resolvconf_is_resolved_symlink(&resolvconf_path) {
return Err(Error::ResolvconfUsesResolved);
}
+
+ if Self::is_dnsmasq_running() && Self::is_dnsmasq_configured_wrong() {
+ return Err(Error::DnsmasqMisconfigurationError);
+ }
+
Ok(Resolvconf {
record_names: HashSet::new(),
resolvconf: resolvconf_path,
@@ -101,4 +110,40 @@ impl Resolvconf {
result
}
+
+ fn is_dnsmasq_running() -> bool {
+ let pid = match fs::read_to_string("/var/run/dnsmasq/dnsmasq.pid") {
+ Ok(pid) => pid,
+ Err(_err) => {
+ return false;
+ }
+ };
+
+ PathBuf::from(format!("/proc/{}/", &pid)).exists()
+ }
+
+ // Have to check whether dnsmasq has been configured to ignore
+ // DNS server lists from external sources
+ // Verify if dnsmasq is configured to ignore any external servers
+ // by checking for the `no-resolv` config option.
+ fn is_dnsmasq_configured_wrong() -> bool {
+ let mut config_paths = fs::read_dir("/etc/dnsmasq.d/")
+ .map(|entries| {
+ entries
+ .into_iter()
+ .filter_map(|entry| entry.ok().map(|e| e.path()))
+ .collect()
+ })
+ .unwrap_or(vec![]);
+
+ config_paths.push(PathBuf::from("/etc/dnsmasq.conf"));
+ config_paths
+ .iter()
+ .filter_map(|file_path| fs::read(file_path).ok())
+ .any(|contents| {
+ String::from_utf8_lossy(contents.as_slice())
+ .lines()
+ .any(|line| line.trim().starts_with("no-resolv"))
+ })
+ }
}