dotlinux guide

DNS Configuration on Linux: A Step-by-Step Guide

The Domain Name System (DNS) is the backbone of the internet, translating human-readable domain names (e.g., example.com) into machine-parseable IP addresses (e.g., 93.184.216.34). For Linux systems—whether servers, desktops, or embedded devices—proper DNS configuration is critical for network connectivity, service reliability, and security. This guide demystifies DNS configuration on Linux, covering fundamental concepts, practical setup steps for common tools (e.g., resolv.conf, systemd-resolved, NetworkManager), troubleshooting techniques, and best practices. By the end, you’ll be able to configure, test, and optimize DNS on any Linux distribution.

Table of Contents

  1. Fundamentals of DNS
    • 1.1 What is DNS?
    • 1.2 How DNS Works
    • 1.3 Common DNS Record Types
  2. Linux DNS Configuration Tools
    • 2.1 The Traditional resolv.conf
    • 2.2 systemd-resolved: Modern DNS Management
    • 2.3 NetworkManager: Desktop/Server Integration
    • 2.4 dnsmasq: Local Caching Resolver
  3. Step-by-Step Configuration Guides
    • 3.1 Configuring resolv.conf Manually
    • 3.2 Using systemd-resolved
    • 3.3 Setting DNS with NetworkManager
    • 3.4 Deploying dnsmasq as a Local Resolver
  4. Testing and Troubleshooting DNS
    • 4.1 Testing DNS Resolution
    • 4.2 Common Issues and Fixes
  5. Best Practices for DNS on Linux
  6. Conclusion
  7. References

1. Fundamentals of DNS

1.1 What is DNS?

DNS is a distributed database that maps domain names to IP addresses. Without DNS, users would need to remember numeric IPs for every website or service, making the internet impractical.

1.2 How DNS Works

DNS resolution follows a hierarchical process:

  1. Local Cache: The OS first checks its local cache for recent lookups.
  2. Recursive Resolver: If not cached, a recursive resolver (e.g., your ISP’s DNS or 8.8.8.8) queries:
    • Root Servers: Direct to Top-Level Domain (TLD) servers (e.g., .com, .org).
    • TLD Servers: Direct to authoritative servers for the domain.
    • Authoritative Servers: Return the final IP address.

1.3 Common DNS Record Types

DNS records define how domains resolve. Key types include:

Record TypePurposeExample
AMaps a domain to an IPv4 addressexample.com. 300 IN A 93.184.216.34
AAAAMaps a domain to an IPv6 addressexample.com. 300 IN AAAA 2606:2800:220:1:248:1893:25c8:1946
CNAMEAlias for another domainwww.example.com. 300 IN CNAME example.com
MXSpecifies mail servers for a domainexample.com. 300 IN MX 10 mail.example.com
TXTStores arbitrary text (e.g., SPF records)example.com. 300 IN TXT "v=spf1 include:example.com ~all"

2. Linux DNS Configuration Tools

Linux offers multiple tools to manage DNS settings, each suited for different environments (e.g., servers, desktops, embedded systems).

2.1 The Traditional resolv.conf

/etc/resolv.conf is the oldest and simplest DNS configuration file. It defines DNS servers and search domains. However, modern systems often manage resolv.conf dynamically via tools like systemd-resolved or NetworkManager, so manual edits may be overwritten.

2.2 systemd-resolved

Part of the systemd ecosystem, systemd-resolved is a system service that manages DNS resolution, caching, and DNSSEC. It replaces traditional resolvers and integrates with systemd-based systems (e.g., Ubuntu 18.04+, Fedora, Debian 10+).

2.3 NetworkManager

A desktop and server network management tool (common on Ubuntu, Fedora, and RHEL), NetworkManager handles dynamic IP/DNS configuration (e.g., via DHCP) and allows manual overrides. It often collaborates with systemd-resolved.

2.4 dnsmasq

A lightweight DNS forwarder and DHCP server, dnsmasq caches DNS queries to speed up resolution and is ideal for local networks, laptops, or embedded devices.

3. Step-by-Step Configuration Guides

3.1 Configuring resolv.conf Manually

Use Case: Legacy systems or environments without systemd/NetworkManager.

Step 1: Edit resolv.conf

Open /etc/resolv.conf with a text editor (e.g., nano):

sudo nano /etc/resolv.conf

Step 2: Add DNS Servers

Add nameserver lines for your preferred DNS servers (e.g., Google DNS, Cloudflare):

# /etc/resolv.conf
nameserver 8.8.8.8    # Google DNS
nameserver 8.8.4.4    # Google DNS (secondary)
nameserver 1.1.1.1    # Cloudflare DNS (optional tertiary)
search example.com    # Append "example.com" to unqualified hostnames (e.g., "server" → "server.example.com")
options timeout:2 attempts:3  # Timeout after 2s, retry 3x

Step 3: Save and Test

Save the file and test resolution with nslookup or dig:

nslookup google.com  # Should return an IP address
dig example.com      # Verify DNS response

Note: On systemd systems, resolv.conf may be a symlink to /run/systemd/resolve/stub-resolv.conf. To force manual management, disable systemd-resolved first:

sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
sudo rm /etc/resolv.conf
sudo touch /etc/resolv.conf  # Recreate as a static file

3.2 Using systemd-resolved

Use Case: Modern systemd-based systems (most Linux distributions today).

Step 1: Verify systemd-resolved is Running

sudo systemctl status systemd-resolved
# Should show "active (running)"

Step 2: Configure Global DNS Servers

Edit /etc/systemd/resolved.conf:

sudo nano /etc/systemd/resolved.conf

Add DNS servers and enable DNSSEC (optional but recommended):

# /etc/systemd/resolved.conf
[Resolve]
DNS=8.8.8.8 8.8.4.4 1.1.1.1  # Space-separated DNS servers
FallbackDNS=9.9.9.9 149.112.112.112  # Fallback if primary fails (Quad9)
Domains=example.com  # Default search domain
DNSSEC=yes  # Enable DNSSEC for security
Cache=yes   # Enable caching

Step 3: Restart the Service

sudo systemctl restart systemd-resolved

Step 4: Verify Configuration

Use resolvectl (the systemd-resolved CLI):

resolvectl status
# Look for "DNS Servers" and "DNSSEC" under "Global"
resolvectl query google.com  # Test resolution

Step 5: Per-Interface DNS (Optional)

To set DNS for a specific interface (e.g., eth0), create a drop-in file:

sudo mkdir -p /etc/systemd/network/eth0.network.d/
sudo nano /etc/systemd/network/eth0.network.d/dns.conf

Add interface-specific DNS:

[Network]
DNS=192.168.1.1  # Local router DNS
Domains=lan  # Search domain for local network

Restart systemd-networkd (if used) and systemd-resolved:

sudo systemctl restart systemd-networkd systemd-resolved

3.3 Setting DNS with NetworkManager

Use Case: Desktops (GNOME/KDE) or servers using NetworkManager for network management.

Step 1: List Network Connections

Identify your connection name (e.g., Wired connection 1 or eth0):

nmcli con show
# Example output: "Wired connection 1" (UUID: ...)

Step 2: Set DNS Servers for a Connection

Override DNS for the connection (replace Wired connection 1 with your connection name):

sudo nmcli con mod "Wired connection 1" ipv4.dns "8.8.8.8,8.8.4.4,1.1.1.1"
sudo nmcli con mod "Wired connection 1" ipv4.ignore-auto-dns yes  # Ignore DHCP-provided DNS

For IPv6, use ipv6.dns and ipv6.ignore-auto-dns.

Step 3: Activate the Changes

sudo nmcli con up "Wired connection 1"

Step 4: Verify

nmcli con show "Wired connection 1" | grep ipv4.dns
# Should show "8.8.8.8,8.8.4.4,1.1.1.1"
resolvectl status  # Confirm DNS servers are active

3.4 Deploying dnsmasq as a Local Resolver

Use Case: Caching DNS queries for faster resolution (e.g., laptops, home labs).

Step 1: Install dnsmasq

# Debian/Ubuntu
sudo apt install dnsmasq

# RHEL/CentOS
sudo dnf install dnsmasq

# Arch
sudo pacman -S dnsmasq

Step 2: Configure dnsmasq

Edit /etc/dnsmasq.conf:

sudo nano /etc/dnsmasq.conf

Add these settings to forward queries to upstream DNS servers and enable caching:

# /etc/dnsmasq.conf
server=8.8.8.8       # Upstream DNS 1
server=8.8.4.4       # Upstream DNS 2
cache-size=1000      # Cache 1000 queries
domain-needed        # Block domains without dots (e.g., "localhost")
bogus-priv           # Block private IPs from public domains
listen-address=127.0.0.1  # Listen on localhost

Step 3: Set dnsmasq as the System Resolver

Point resolv.conf to dnsmasq (localhost:53):

# If using systemd-resolved, disable it first:
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
sudo rm /etc/resolv.conf
echo "nameserver 127.0.0.1" | sudo tee /etc/resolv.conf

Step 4: Start dnsmasq

sudo systemctl enable --now dnsmasq
sudo systemctl status dnsmasq  # Verify it’s running

Step 5: Test Caching

First query (uncached, slower):

time dig google.com

Second query (cached, faster):

time dig google.com  # Should return in <10ms

4. Testing and Troubleshooting DNS

4.1 Testing DNS Resolution

Use these tools to validate DNS functionality:

  • dig: Detailed DNS query tool (install via bind-utils on RHEL/CentOS):

    dig google.com A  # Query A record for google.com
    dig example.com MX  # Query mail servers
  • nslookup: Simple resolver:

    nslookup google.com
  • resolvectl (with systemd-resolved):

    resolvectl query example.com

4.2 Common Issues and Fixes

Issue 1: resolv.conf is Overwritten

Fix: Identify the tool managing resolv.conf (e.g., systemd-resolved, NetworkManager). Use the tool’s native configuration (e.g., resolved.conf or nmcli) instead of editing resolv.conf directly.

Issue 2: DNS Queries Time Out

Check:

  • Firewall blocking port 53 (UDP/TCP):
    sudo ufw status  # Check UFW rules
    sudo iptables -L  # Check iptables
  • Upstream DNS servers are unreachable:
    ping 8.8.8.8  # Test connectivity to Google DNS

Issue 3: Slow Resolution

Fix: Use a caching resolver like dnsmasq or ensure systemd-resolved caching is enabled (Cache=yes in resolved.conf).

Issue 4: DNSSEC Failures

Fix: Temporarily disable DNSSEC (DNSSEC=no in resolved.conf) to test if the upstream server lacks DNSSEC support. Use DNSSEC-enabled servers like Cloudflare (1.1.1.1) or Quad9 (9.9.9.9).

5. Best Practices for DNS on Linux

  1. Use Redundant DNS Servers: Always configure 2–3 upstream DNS servers (e.g., 8.8.8.8, 1.1.1.1, 9.9.9.9) to avoid single points of failure.

  2. Prioritize Local DNS for Internal Networks: For home/office networks, use your router’s DNS or a local resolver (e.g., dnsmasq) to speed up internal domain resolution.

  3. Enable DNSSEC: Prevent cache poisoning attacks by enabling DNSSEC (supported by systemd-resolved and dnsmasq).

  4. Encrypt DNS Traffic: Use DNS over HTTPS (DoH) or DNS over TLS (DoT) to protect queries from eavesdropping. With systemd-resolved, enable DoT:

    # In resolved.conf
    DNSOverTLS=yes
    DNS=1.1.1.1  # Cloudflare supports DoT
  5. Avoid Hardcoding IPs: Use hostnames instead of IPs in config files (e.g., /etc/hosts for local overrides) to simplify maintenance.

  6. Monitor DNS Performance: Track query latency and failures with tools like dnsperf or prometheus + blackbox-exporter.

6. Conclusion

DNS configuration is a cornerstone of Linux network management, impacting everything from web browsing to service availability. By understanding tools like systemd-resolved, NetworkManager, and dnsmasq, and following best practices like redundancy, encryption, and caching, you can ensure reliable, secure, and fast DNS resolution.

Whether you’re managing a server farm or a personal laptop, the steps in this guide will help you master DNS on Linux.

7. References