When working with multiple VPN connections simultaneously, DNS resolution becomes particularly tricky. The standard /etc/resolv.conf
approach often fails when you need:
- A primary VPN handling general DNS queries
- Secondary VPNs serving specific internal domains
- Domain-specific DNS resolution without leaking queries
The default behavior of resolv.conf
processes nameservers sequentially, not domain-specifically. Given this configuration:
nameserver 10.8.0.1
search mydomain.local
nameserver 10.250.0.2
All queries will hit 10.8.0.1 first, regardless of the target domain. Only if that fails will it try 10.250.0.2 - which isn't what we want for domain-specific resolution.
For Linux systems, we have several better approaches:
1. Using systemd-resolved
Modern Linux distributions often use systemd-resolved as the DNS resolver. Create domain-specific configurations:
sudo systemd-resolve --interface=tun0 --set-dns=10.8.0.1
sudo systemd-resolve --interface=tun1 --set-dns=10.250.0.2 --set-domain=mydomain.local
Then check with:
resolvectl status
2. dnsmasq Configuration
For more control, configure dnsmasq as your local resolver:
# /etc/dnsmasq.conf
server=/mydomain.local/10.250.0.2
server=10.8.0.1
Then point /etc/resolv.conf
to 127.0.0.1.
3. NetworkManager Domain Matching
If using NetworkManager, edit connection profiles:
[connection]
id=Corporate VPN
uuid=...
type=vpn
[ipv4]
dns=10.250.0.2;
dns-search=mydomain.local;
dns-priority=100
Always verify your configuration with these tools:
dig @10.250.0.2 internal.mydomain.local
nslookup -debug internal.mydomain.local 10.250.0.2
systemd-resolve --status | grep -A5 "DNS Domain"
Remember that VPN clients often overwrite /etc/resolv.conf
, so you may need to disable this behavior in your VPN client configuration or use immutable resolv.conf:
sudo chattr +i /etc/resolv.conf
When working with multiple VPN connections that each require different DNS configurations, the traditional /etc/resolv.conf
approach shows its limitations. Let me share my experience solving this exact problem.
The default behavior of resolv.conf
is sequential DNS resolution - it tries servers in order until it gets a response. For your case:
nameserver 10.8.0.1
search mydomain.local
nameserver 10.250.0.2
This won't work because:
- All queries first hit 10.8.0.1
- The search domain doesn't affect server selection
- 10.250.0.2 only gets queries that timeout on 10.8.0.1
Most modern Linux distributions use systemd-resolved as the DNS resolver. Here's how to properly configure domain-specific DNS:
# Create or edit the configuration
sudo nano /etc/systemd/resolved.conf.d/vpn-domains.conf
# Add domain-specific DNS configuration
[Resolve]
DNS=10.8.0.1
Domains=~.
DNS=10.250.0.2
Domains=mydomain.local
Then restart the service:
sudo systemctl restart systemd-resolved
For systems without systemd-resolved, dnsmasq offers excellent domain-specific routing:
# Install if needed
sudo apt install dnsmasq
# Configure /etc/dnsmasq.conf
server=/mydomain.local/10.250.0.2
server=10.8.0.1
Make sure to disable other DNS services and point resolv.conf to localhost:
nameserver 127.0.0.1
Check your configuration with:
systemd-resolve --status
# or for dnsmasq
dig @127.0.0.1 mydomain.local
For troubleshooting, use these commands:
# Check which server resolves a domain
host -v mydomain.local
# Test query path
dig +trace mydomain.local
Remember these important points:
- VPN interfaces may overwrite resolv.conf - use hooks or persistent configs
- Some applications bypass system DNS (like Chrome with DoH)
- TTL values can affect how quickly changes propagate