The Domain Name System (DNS) is the backbone of the internet, translating human-readable domain names (e.g., example.com) into machine-readable IP addresses (e.g., 93.184.216.34). A DNS resolver is a critical client-side component that initiates and manages these translation requests. On Linux systems, configuring the DNS resolver properly ensures reliable, fast, and secure name resolution—essential for everything from web browsing to server communication. This blog explores DNS resolver configuration on Linux in depth, covering fundamental concepts, key configuration files, practical usage methods, common practices, and best practices. Whether you’re a system administrator, developer, or Linux enthusiast, this guide will help you master resolver setup and troubleshooting.
Table of Contents
- Fundamental Concepts
- Key Configuration Files
- Usage Methods
- Common Practices
- Best Practices
- Troubleshooting Common Issues
- Conclusion
- References
Fundamental Concepts
What is a DNS Resolver?
A DNS resolver (or “recursive resolver”) is software running on your Linux system that acts as an intermediary between client applications (e.g., browsers, curl) and DNS authoritative servers. Its primary role is to:
- Accept domain name queries from applications.
- Recursively query authoritative DNS servers to resolve the domain to an IP.
- Cache results to speed up future queries.
Linux systems typically use resolvers like systemd-resolved, dnsmasq, or the legacy BIND resolver. Modern distributions often default to systemd-resolved for integration with systemd services.
How DNS Resolution Works
DNS resolution follows a step-by-step process:
- Local Cache Check: The resolver first checks its local cache for a recent entry. If found, it returns the IP immediately.
- Recursive Query: If not cached, the resolver sends a query to a root DNS server, which directs it to a top-level domain (TLD) server (e.g.,
.com). - TLD and Authoritative Server Query: The TLD server points to the domain’s authoritative server, which holds the final IP address.
- Response and Caching: The resolver returns the IP to the client and caches the result for future use.
Example: Resolving example.com involves queries to root servers (.), TLD servers (.com), and example.com’s authoritative server.
Key Configuration Files
Linux resolver behavior is controlled by several critical files and services. Below are the most important ones.
/etc/resolv.conf: The Classic Resolver File
The /etc/resolv.conf file is the traditional configuration point for DNS resolvers. It defines:
- DNS servers to query (
nameserver). - Search domains for unqualified names (e.g.,
host→host.example.comviasearch). - Timeouts and retry logic (
options).
Example resolv.conf:
# Define primary and secondary DNS servers
nameserver 8.8.8.8 # Google DNS
nameserver 8.8.4.4 # Google DNS (secondary)
# Search domain for unqualified names (e.g., "server" → "server.example.com")
search example.com sub.example.com
# Resolver options: timeout (5s), 2 retries, enable DNSSEC validation
options timeout:5 attempts:2 edns0 trust-ad
Key Directives:
nameserver <IP>: IP address of a DNS resolver (max 3 entries).search <domains>: Space-separated list of domains to append to unqualified names.domain <domain>: Single search domain (overridden bysearchif present).options <flags>: Resolver behavior (e.g.,timeout:Nfor query timeout,attempts:Nfor retries,edns0for DNS extensions,trust-adto trust DNSSEC signatures).
systemd-resolved: Modern Resolver Management
Most modern Linux distributions (e.g., Ubuntu 20.04+, Fedora, Debian 11+) use systemd-resolved as the primary resolver. It integrates with systemd and manages /etc/resolv.conf dynamically, often via a symlink:
ls -l /etc/resolv.conf
# Output: lrwxrwxrwx 1 root root 39 Aug 1 12:00 /etc/resolv.conf -> /run/systemd/resolve/stub-resolv.conf
systemd-resolved provides:
- A stub resolver (listening on
127.0.0.53:53) that forwards queries to configured DNS servers. - Per-interface DNS configuration (e.g., different DNS for Wi-Fi vs. Ethernet).
- Built-in caching and DNSSEC support.
To check resolver status:
resolvectl status
NetworkManager: Dynamic Network Configuration
NetworkManager (used by most desktop and server distributions) manages network connections and often controls DNS resolver settings. It overrides /etc/resolv.conf by default, pushing DNS servers from DHCP or user-defined settings to systemd-resolved.
Key NetworkManager concepts:
- Connections: Stored profiles for networks (e.g., “Wired Connection 1”).
- Per-connection DNS: Set DNS servers for specific networks.
/etc/nsswitch.conf: Name Service Switch
The nsswitch.conf file defines the order in which Linux looks up names (e.g., users, hosts). For DNS, the hosts line determines resolution priority:
# /etc/nsswitch.conf excerpt
hosts: files dns myhostname
files: Check/etc/hostsfirst.dns: Use DNS resolver next.myhostname: Resolve the local hostname (viasystemd-resolved).
Changing the order (e.g., dns files) prioritizes DNS over /etc/hosts, but this is rarely recommended.
Usage Methods
Manual Configuration with /etc/resolv.conf
Warning: On systems with NetworkManager or systemd-resolved, manual edits to /etc/resolv.conf may be overwritten. Use this method only for static, non-network-managed environments.
Steps:
- Edit
/etc/resolv.confwith a text editor:sudo nano /etc/resolv.conf - Add
nameserver,search, andoptionsdirectives (see example above). - Save and exit.
Persistence Note:
To prevent overwrites, set chattr +i /etc/resolv.conf (immutable flag), but this is not recommended for dynamic networks.
Configuring systemd-resolved
systemd-resolved is configured via resolvectl (command-line tool) or drop-in files.
Set Global DNS Servers:
Override the default DNS servers for all interfaces:
# Create a drop-in configuration for systemd-resolved
sudo mkdir -p /etc/systemd/resolved.conf.d/
sudo nano /etc/systemd/resolved.conf.d/custom-dns.conf
Add:
[Resolve]
DNS=1.1.1.1 1.0.0.1 # Cloudflare DNS
FallbackDNS=8.8.8.8 8.8.4.4 # Google DNS (fallback)
Domains=example.com # Default search domain
DNSSEC=yes # Enable DNSSEC validation
Restart systemd-resolved to apply:
sudo systemctl restart systemd-resolved
Set Per-Interface DNS:
Override DNS for a specific interface (e.g., wlan0):
resolvectl dns wlan0 9.9.9.9 149.112.112.112 # Quad9 DNS
resolvectl domain wlan0 "home.lan" # Search domain for wlan0
NetworkManager Integration
Use nmcli (NetworkManager CLI) to configure DNS for a connection.
Example: Set DNS for “Wired Connection 1”
# List connections to find the name/UUID
nmcli con show
# Set DNS servers and disable auto-DNS from DHCP
nmcli con mod "Wired Connection 1" \
ipv4.dns "8.8.8.8,8.8.4.4" \
ipv4.ignore-auto-dns yes \
ipv4.dns-search "example.com" # Search domain
# Apply changes
nmcli con up "Wired Connection 1"
Verify with resolvectl:
resolvectl dns "Wired Connection 1"
# Output: Link 2 (enp0s3): 8.8.8.8 8.8.4.4
Common Practices
Testing DNS Resolution
Use these tools to validate resolver behavior:
dig: DNS Lookup Tool
# Basic lookup (uses system resolver)
dig example.com
# Query a specific DNS server (e.g., Cloudflare)
dig @1.1.1.1 example.com
# Check DNSSEC status (look for "ad" flag in response)
dig +dnssec example.com
nslookup/host: Simpler Alternatives
nslookup example.com # Uses system resolver
host example.com 8.8.8.8 # Query Google DNS
Check Caching:
# First query (no cache)
dig example.com | grep "Query time"
# Second query (cached, faster)
dig example.com | grep "Query time"
Setting Up Local Caching
Local caching reduces latency and DNS traffic. Most modern resolvers (e.g., systemd-resolved, dnsmasq) cache by default.
Verify systemd-resolved Caching:
resolvectl statistics
# Look for "Cache hits" and "Cache misses" under "DNSSEC supported"
Advanced: Use dnsmasq as a Local Cache
For more control, install dnsmasq (lightweight DNS forwarder/cache):
sudo apt install dnsmasq # Debian/Ubuntu
sudo yum install dnsmasq # RHEL/CentOS
# Configure dnsmasq to listen on localhost and forward to Cloudflare
echo "listen-address=127.0.0.1" | sudo tee -a /etc/dnsmasq.conf
echo "server=1.1.1.1" | sudo tee -a /etc/dnsmasq.conf
echo "server=1.0.0.1" | sudo tee -a /etc/dnsmasq.conf
sudo systemctl restart dnsmasq
# Set resolver to 127.0.0.1 (via systemd-resolved or resolv.conf)
resolvectl dns lo 127.0.0.1
Using Public DNS Servers
Public DNS servers often offer faster speeds, better security, or privacy compared to ISP-provided resolvers. Popular options:
| Provider | Primary DNS | Secondary DNS | Features |
|---|---|---|---|
| Cloudflare | 1.1.1.1 | 1.0.0.1 | Fast, privacy-focused |
8.8.8.8 | 8.8.4.4 | Reliable, global | |
| Quad9 | 9.9.9.9 | 149.112.112.112 | Blocks malicious domains |
| OpenDNS | 208.67.222.222 | 208.67.220.220 | Family filtering options |
To use Quad9, configure via resolvectl:
resolvectl dns enp0s3 9.9.9.9 149.112.112.112
Best Practices
Avoid Hardcoding Resolvers
Hardcoding /etc/resolv.conf is error-prone (e.g., overwritten by NetworkManager). Instead:
- Use
systemd-resolveddrop-in files for global settings. - Use
NetworkManagerper-connection DNS for dynamic networks.
Secure DNS Queries with DNSSEC, DoT, and DoH
DNS is vulnerable to spoofing and eavesdropping. Mitigate risks with:
DNSSEC (Domain Name System Security Extensions)
Validates DNS responses to prevent tampering. Enable via systemd-resolved:
# /etc/systemd/resolved.conf.d/security.conf
[Resolve]
DNSSEC=yes # "yes" = enforce, "allow-downgrade" = soft enforcement
DNS over TLS (DoT, RFC 7858)
Encrypts DNS queries between resolver and server (port 853). Configure with systemd-resolved:
# /etc/systemd/resolved.conf.d/dot.conf
[Resolve]
DNS=1.1.1.1#cloudflare-dns.com 9.9.9.9#dns.quad9.net # DoT servers
DNSOverTLS=yes # "yes" = enforce, "opportunistic" = try but allow plaintext
DNS over HTTPS (DoH, RFC 8484)
Encrypts DNS over HTTPS (port 443). Use tools like cloudflared (Cloudflare’s DoH proxy):
sudo cloudflared proxy-dns # Runs on 127.0.0.1:53
# Configure resolver to use 127.0.0.1
Monitor and Log Resolver Activity
Logging helps debug resolution issues and detect abuse.
systemd-resolved Logs:
journalctl -u systemd-resolved -f # Follow live logs
journalctl -u systemd-resolved --since "10m ago" # Logs from last 10 minutes
Key Log Entries to Watch:
DNSSEC validation failed: Indicates invalid DNSSEC records.Timeout resolving: Slow or unresponsive DNS servers.
Handle Dynamic Networks Gracefully
In mobile or VPN environments, DNS servers may change frequently. Use:
NetworkManagerorsystemd-networkdto auto-update resolvers.- Split DNS (per-domain resolvers) for VPNs:
# Example: Route *.corp.example.com queries to VPN DNS resolvectl domain tun0 "corp.example.com" resolvectl dns tun0 10.0.0.1 # VPN DNS server
Troubleshooting Common Issues
1. /etc/resolv.conf is Overwritten
Cause: NetworkManager or systemd-resolved manages the file.
Fix: Use the service’s native configuration (e.g., nmcli for NetworkManager, resolvectl for systemd-resolved).
2. DNS Resolution Fails
Checklist:
- Verify nameservers:
cat /etc/resolv.conforresolvectl dns. - Test with a public DNS:
dig @8.8.8.8 example.com. - Ensure resolver service is running:
systemctl status systemd-resolved. - Check firewall rules (allow UDP/TCP port 53).
3. Slow DNS Queries
Fixes:
- Use closer DNS servers (e.g., Cloudflare/Google instead of ISP).
- Enable caching (ensure
systemd-resolvedordnsmasqis running). - Reduce
timeout/attemptsinresolv.confoptions:options timeout:2 attempts:1 # 2-second timeout, 1 retry
4. DNSSEC Validation Errors
Cause: Misconfigured DNSSEC or untrusted records.
Fix:
- Use
DNSSEC=allow-downgradeinsystemd-resolvedfor soft enforcement.