Skip to content

Commit 2c30a11

Browse files
committed
Fix DNS resolution for VPN and private network configurations
PR #167 introduced DNS filtering that excluded all private IP addresses (10.x, 172.16-31.x, 192.168.x, fc00::/7) assuming they would be unreachable from QEMU's slirp networking. However, this breaks VPN scenarios where private DNS servers are actually reachable. This change removes the overly aggressive private IP filtering, now only filtering out localhost and link-local addresses. Private network DNS servers are allowed through since they may be reachable (e.g., via VPN or air-gapped networks). If they're actually unreachable, DNS will fail naturally, which is better than prematurely filtering them out. Also downgraded the fallback warning from WARN to debug level since falling back to public DNS is a normal case, not an error condition. Assisted-by: Claude Code (Sonnet 4.5) Signed-off-by: gursewak1997 <gursmangat@gmail.com>
1 parent 0fd3599 commit 2c30a11

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

crates/kit/src/run_ephemeral.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -326,23 +326,23 @@ fn read_host_dns_servers() -> Option<Vec<String>> {
326326
Ok(content) => {
327327
let dns_servers = parse_resolv_conf(&content);
328328

329-
// Filter out localhost, link-local, and private network addresses
330-
// QEMU runs in user networking mode (slirp) inside a container, which cannot
331-
// reach private network addresses (10.x.x.x, 172.16-31.x.x, 192.168.x.x for IPv4,
332-
// fc00::/7 ULA for IPv6). These are often VPN-only DNS servers that won't work.
333-
// We'll fall back to public DNS (8.8.8.8, 1.1.1.1) which is more reliable.
329+
// Filter out localhost and link-local addresses only
330+
// Private network addresses (10.x, 172.16-31.x, 192.168.x, fc00::/7) are allowed
331+
// because they may be reachable from the container/VM (e.g., VPN DNS servers).
332+
// If they're unreachable, DNS will fail naturally, but filtering them out
333+
// prematurely causes issues with VPN configurations and air-gapped environments.
334334
let filtered_servers: Vec<String> = dns_servers
335335
.into_iter()
336336
.filter(|s| {
337337
// Try parsing as IPv4 first
338338
if let Ok(ip) = s.parse::<std::net::Ipv4Addr>() {
339-
// Reject loopback, link-local, and private addresses
340-
!ip.is_loopback() && !ip.is_link_local() && !ip.is_private()
339+
// Reject loopback and link-local addresses only
340+
!ip.is_loopback() && !ip.is_link_local()
341341
} else if let Ok(ip) = s.parse::<std::net::Ipv6Addr>() {
342-
// Reject loopback (::1), link-local (fe80::/10), ULA (fc00::/7), and multicast
343-
!ip.is_loopback() && !ip.is_multicast()
342+
// Reject loopback (::1), link-local (fe80::/10), and multicast
343+
!ip.is_loopback()
344+
&& !ip.is_multicast()
344345
&& !(ip.segments()[0] & 0xffc0 == 0xfe80) // link-local fe80::/10
345-
&& !(ip.segments()[0] & 0xfe00 == 0xfc00) // ULA fc00::/7 (private)
346346
} else {
347347
false // Reject invalid addresses
348348
}
@@ -586,9 +586,9 @@ fn prepare_run_command_with_temp(
586586
// which would otherwise contain unreachable bridge DNS servers (e.g., 169.254.1.1).
587587
// Using --dns properly configures /etc/resolv.conf in the container.
588588
let host_dns_servers = read_host_dns_servers().or_else(|| {
589-
// Fallback to public DNS if no usable DNS found in system configuration
590-
// This ensures DNS works even when host has broken/unreachable DNS config
591-
warn!("No usable DNS servers found in system configuration, falling back to public DNS (8.8.8.8, 1.1.1.1). This may not work in air-gapped environments.");
589+
// Fallback to public DNS if no DNS servers found in system configuration
590+
// This ensures DNS works in most cases, but may fail in air-gapped or VPN-only environments
591+
debug!("No DNS servers found in system configuration, falling back to public DNS (8.8.8.8, 1.1.1.1)");
592592
Some(vec!["8.8.8.8".to_string(), "1.1.1.1".to_string()])
593593
});
594594

0 commit comments

Comments
 (0)