Stackvora.tech

Configure DNS on Modern Linux With systemd-resolved

Modern Linux distributions, particularly those utilizing systemd , have largely transitioned their DNS resolution management from the traditional libc…

Modern Linux distributions, particularly those utilizing systemd, have largely transitioned their DNS resolution management from the traditional libc resolver and static /etc/resolv.conf to systemd-resolved. This service acts as a caching and validating stub resolver, providing DNS resolution to local applications. Understanding its operation is crucial for reliable network communication on contemporary Linux systems.

This article details the configuration of DNS settings using systemd-resolved, covering both temporary runtime changes and persistent configurations across various network management tools, and provides methods for verifying resolver status and troubleshooting common issues.

Understanding systemd-resolved's Role

systemd-resolved is a system service that manages network name resolution. It provides a local DNS stub resolver, which means applications don't directly query remote DNS servers. Instead, they query systemd-resolved on 127.0.0.53 (by default), which then forwards queries to upstream DNS servers configured for specific interfaces or globally. This architecture offers several benefits:

  • Caching: Reduces latency and upstream server load by caching responses.
  • DNSSEC Validation: Can validate DNS responses to protect against spoofing.
  • Split DNS: Allows different DNS servers to be used for different domains or interfaces.
  • Dynamic Configuration: Integrates seamlessly with network managers like NetworkManager, Netplan, and systemd-networkd for automatic DNS updates.

On most current distributions (e.g., Ubuntu 18.04+, Debian 10+, Fedora 28+), the traditional /etc/resolv.conf file is a symbolic link to /run/systemd/resolve/stub-resolv.conf or /run/systemd/resolve/resolv.conf. Directly editing this file is generally discouraged, as systemd-resolved (or other network managers) will overwrite it upon network changes or service restarts. The content of stub-resolv.conf typically points applications to the local systemd-resolved stub resolver:

nameserver 127.0.0.53
options edns0 trust-ad
search mydomain.local

Runtime DNS Configuration with resolvectl

The resolvectl utility is the primary command-line tool for interacting with systemd-resolved. It allows you to view the current DNS configuration and temporarily override settings.

Viewing Current Status

To inspect the current DNS server configuration for all interfaces and the global settings:

$ resolvectl status
Global
       Protocols: LLMNR mDNS DNSOverTLS=no
resolv.conf mode: stub
     DNSSEC NTA: 10.in-addr.arpa 16.172.in-addr.arpa 17.172.in-addr.arpa 18.172.in-addr.arpa 19.172.in-addr.arpa 20.172.in-addr.arpa 21.172.in-addr.arpa 22.172.in-addr.arpa 23.172.in-addr.arpa 24.172.in-addr.arpa 25.172.in-addr.arpa 26.172.in-addr.arpa 27.172.in-addr.arpa 28.172.in-addr.arpa 29.172.in-addr.arpa 30.172.in-addr.arpa 31.172.in-addr.arpa 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa 2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa

Link 2 (eth0)
    Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
         Protocols: +DefaultRoute +LLMNR -mDNS +DNSOverTLS=no
Current DNS Server: 192.168.1.1
       DNS Servers: 192.168.1.1 8.8.8.8
        DNS Domain: mylan.local

Link 3 (wlan0)
    Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
         Protocols: +DefaultRoute +LLMNR -mDNS +DNSOverTLS=no
Current DNS Server: 192.168.1.1
       DNS Servers: 192.168.1.1 8.8.4.4
        DNS Domain: mywifinet.home

This output shows the global settings, the resolv.conf mode (stub implies 127.0.0.53 is used), and specific DNS servers configured for each active network interface (e.g., eth0, wlan0).

Setting DNS Servers

To set DNS servers for a specific interface (e.g., eth0) at runtime, overriding DHCP-provided servers:

sudo resolvectl dns eth0 1.1.1.1 9.9.9.9

This command immediately configures Cloudflare's and Quad9's DNS servers for eth0. The changes are effective immediately but are not persistent across reboots or network reconfigurations.

To clear custom DNS servers for an interface and revert to DHCP-provided or global defaults:

sudo resolvectl revert eth0

Setting DNS Search Domains

You can also set DNS search domains for an interface:

sudo resolvectl domain eth0 mycorp.com internal.mycorp.com

This makes it possible to resolve unqualified hostnames like appserver to appserver.mycorp.com or appserver.internal.mycorp.com.

Persistent DNS Configuration

For persistent DNS settings, configuration needs to be done through the network management tool in use on your system. Common tools include NetworkManager, Netplan, and systemd-networkd.

NetworkManager (Common on Desktops/Laptops)

NetworkManager often manages DNS settings, pulling them from DHCP or allowing manual configuration. There are several ways to configure it persistently:

  1. Graphical User Interface (GUI): For desktop environments (GNOME, KDE), navigate to network settings, select your connection, and manually enter DNS servers.
  2. nmcli (Command Line Interface): For a wired connection named "Wired connection 1" (or similar):
    sudo nmcli connection modify "Wired connection 1" ipv4.dns "8.8.8.8 8.8.4.4"
    sudo nmcli connection modify "Wired connection 1" ipv4.dns-search "mydomain.local"
    sudo nmcli connection modify "Wired connection 1" ipv4.method manual # If using static IP, otherwise auto
    sudo nmcli connection up "Wired connection 1"
    For a Wi-Fi connection named "MyWiFi":
    sudo nmcli connection modify MyWiFi ipv4.dns "1.1.1.1 1.0.0.1"
    sudo nmcli connection modify MyWiFi ipv4.dns-search "~." # To disable specific search domains
    sudo nmcli connection up MyWiFi
    The ~. syntax for ipv4.dns-search prevents NetworkManager from setting any search domains for that specific connection, effectively clearing them.
  3. Configuration Files (/etc/NetworkManager/system-connections/): Edit the respective connection file directly. This is less common but possible. For example, for an Ethernet connection:
    [ipv4]
    method=auto
    dns=8.8.8.8;8.8.4.4;
    dns-search=mydomain.local;
    Then reload NetworkManager: sudo systemctl reload NetworkManager.

Netplan (Common on Ubuntu Servers)

Netplan uses YAML configuration files in /etc/netplan/. A typical configuration for a static IP with custom DNS:

# /etc/netplan/01-netcfg.yaml
network:
  version: 2
  renderer: networkd # or NetworkManager
  ethernets:
    eth0:
      dhcp4: no
      addresses:
        - 192.168.1.100/24
      routes:
        - to: default
          via: 192.168.1.1
      nameservers:
        addresses: [1.1.1.1, 9.9.9.9]
        search: [mydomain.local, internal.local]

After modifying the Netplan YAML file, apply the changes:

sudo netplan try # Validates syntax before applying
sudo netplan apply

systemd-networkd (Common on minimal systemd systems)

systemd-networkd manages network interfaces using .network files in /etc/systemd/network/. An example for eth0:

# /etc/systemd/network/20-wired.network
[Match]
Name=eth0

[Network]
DHCP=ipv4
DNS=8.8.8.8 8.8.4.4
Domains=mydomain.local internal.local

If you prefer a static configuration:

# /etc/systemd/network/20-static.network
[Match]
Name=eth0

[Network]
Address=192.168.1.100/24
Gateway=192.168.1.1
DNS=1.1.1.1 9.9.9.9
Domains=mydomain.local

After creating or modifying the .network file, reload systemd-networkd:

sudo systemctl restart systemd-networkd
sudo systemctl restart systemd-resolved # To ensure resolved picks up changes

Verifying DNS Resolution

After configuring DNS, always verify that queries are resolving correctly and using the intended servers.

  • resolvectl status: As shown above, this command provides an overview of all configured DNS servers and domains per link. The "Current DNS Server" line indicates the server systemd-resolved is currently actively using for that link.
  • resolvectl query example.com: This command directly queries systemd-resolved for a specific domain. It shows the response and which DNS server was used.
    $ resolvectl query stackvora.tech
    stackvora.tech: 172.67.147.200
                    104.21.94.135
                    104.21.94.135
                    172.67.147.200
    
    -- Link 2 (eth0)
    -- Link 3 (wlan0)
    -- Link 4 (docker0)
    -- Link 5 (br-a39c0f0a4023)
    The output indicates which interface(s) resolved the query, helping to debug split DNS issues.
  • dig @127.0.0.53 example.com: This command explicitly uses the systemd-resolved stub listener. The ANSWER SECTION shows the resolved IPs.
  • dig example.com: This command uses the standard system resolver (which, via /etc/resolv.conf, points to 127.0.0.53).

Common Pitfalls and Troubleshooting

  • /etc/resolv.conf overwritten: Never manually edit /etc/resolv.conf if it's a symlink to a systemd-resolved file. Your changes will be lost. Configure via your network manager instead.
  • Services not restarting: After making persistent DNS changes (especially with systemd-networkd or NetworkManager), ensure you apply/reload the configuration and restart affected services. A sudo systemctl restart systemd-resolved is often necessary after direct configuration file edits.
  • Incorrect DNS server addresses: Double-check for typos in IP addresses. Verify the accessibility of your chosen DNS servers (e.g., ping 1.1.1.1).
  • Firewall blocking DNS (UDP/TCP 53): Ensure no local firewall rules (ufw, firewalld, iptables) are blocking outgoing DNS queries from systemd-resolved or incoming queries to 127.0.0.53.
  • DNS cache issues: If you're experiencing stale DNS records, you can clear systemd-resolved's cache:
    sudo resolvectl flush-caches
    This is particularly useful when testing DNS changes or after domain migration.
  • DNSSEC validation failures: If DNSSEC validation failed appears in logs or resolvectl status, it might indicate issues with the upstream DNS server's support for DNSSEC or a misconfiguration. You can disable DNSSEC validation globally in /etc/systemd/resolved.conf by setting DNSSEC=no, but this reduces security.
  • Conflicting network managers: Ensure only one network management daemon (e.g., NetworkManager, systemd-networkd) is actively managing a given interface to avoid conflicts.

Back to the knowledge base · Ask the AI assistant