Running systemd-resolved to cache DNS queries with NetworkManager

rwxd June 16, 2025 #linux #network #dns #NetworkManager #systemd-resolved

This post describes how to set up systemd-resolved to cache DNS queries with NetworkManager. Using systemd-resolved provides several benefits:

Why Use systemd-resolved?

Traditional DNS resolution on Linux can be fragmented across different applications and configuration files. systemd-resolved provides a unified approach that works well with modern Linux distributions and NetworkManager.

Configure NetworkManager

First, configure NetworkManager to use systemd-resolved for DNS resolution:

In /etc/NetworkManager/NetworkManager.conf under the [main] section, add the following line:

[main]
dns=systemd-resolved

This instructs NetworkManager to pass DNS server information from network connections to systemd-resolved.

Reload the NetworkManager configuration to apply the changes:

sudo nmcli general reload

Configure systemd-resolved

Installation

Install systemd-resolved if it is not already installed:

# For Fedora/RHEL/CentOS
sudo dnf install systemd-resolved

# For Debian/Ubuntu
sudo apt install systemd-resolved

# For Arch Linux
sudo pacman -S systemd-resolved

Configuration

Edit the /etc/systemd/resolved.conf file to set the DNS servers and other options. Here's an example configuration using Quad9 as the global DNS provider with DNSSEC and DNS-over-TLS enabled:

[Resolve]
# Quad9 secure DNS servers (blocks malicious domains)
DNS=9.9.9.9#dns.quad9.net 2620:fe::fe#dns.quad9.net
FallbackDNS=149.112.112.112#dns.quad9.net 2620:fe::9#dns.quad9.net

# Security features
DNSSEC=yes
DNSOverTLS=yes

# Caching
Cache=yes

# Local resolution
DNSStubListener=yes
ReadEtcHosts=yes

Note: The #dns.quad9.net suffix enables DNS-over-TLS for that server.

Alternative DNS Providers

You can replace Quad9 with other providers:

# Cloudflare
DNS=1.1.1.1#cloudflare-dns.com 2606:4700:4700::1111#cloudflare-dns.com
FallbackDNS=1.0.0.1#cloudflare-dns.com 2606:4700:4700::1001#cloudflare-dns.com

# Google
DNS=8.8.8.8#dns.google 2001:4860:4860::8888#dns.google
FallbackDNS=8.8.4.4#dns.google 2001:4860:4860::8844#dns.google

Enable and Start the Service

Now enable and start the systemd-resolved service:

sudo systemctl enable --now systemd-resolved
sudo systemctl status systemd-resolved

Configure resolv.conf

To make applications use systemd-resolved, link the stub resolver to /etc/resolv.conf:

# Backup the existing resolv.conf
sudo mv /etc/resolv.conf /etc/resolv.conf.bak

# Create the symlink
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

# Reload NetworkManager to apply changes immediately (not needed at reboot)
sudo nmcli general reload

# Verify the configuration
cat /etc/resolv.conf

Important: The stub-resolv.conf points to 127.0.0.53, which is systemd-resolved's stub resolver address.

Verify and Troubleshoot

Test DNS Resolution

Query the stub resolver to verify it's working:

dig google.com @127.0.0.53 +short

Check Interface Configurations

View DNS settings for all network interfaces:

resolvectl status

This shows which DNS servers are being used for each connection.

Monitor DNS Queries in Real-time

sudo resolvectl monitor

View Cache Statistics

resolvectl statistics

View Cache Entries

To see what's currently in the DNS cache:

resolvectl show-cache

Managing DNS Settings

Per-Connection DNS Settings

NetworkManager can set different DNS servers for each connection, which systemd-resolved will respect:

# Set specific DNS servers for a connection
sudo nmcli connection modify "My Connection" ipv4.dns "1.1.1.1 8.8.8.8"
sudo nmcli connection modify "My Connection" ipv6.dns "2606:4700:4700::1111 2001:4860:4860::8888"

# Remove specific DNS configuration from a connection
sudo nmcli connection modify "My Connection" ipv4.dns ""
sudo nmcli connection modify "My Connection" ipv6.dns ""

Flush DNS Cache

If you need to clear the DNS cache:

sudo resolvectl flush-caches