Why RHEL 9’s systemd‑resolved Is the Smart DNS Choice for Modern Workloads
RHEL 9 ships with systemd‑resolved, a DNS stub resolver that adds caching and DNSSEC. This blog walks through enabling it, configuring Cloudflare’s DNSSEC‑enabled servers, and verifying cache hits while highlighting migration trade‑offs.
17 Apr 2026, 20:51 UTC

The DNS Problem on RHEL 9
On RHEL 9, the traditional glibc resolver still reads /etc/resolv.conf to find nameservers. That file is static, can be overwritten by NetworkManager or networkd, and offers no built‑in caching or DNSSEC validation. In an environment where every microservice needs fast name resolution and strict security, the default setup can become a bottleneck and a security risk.
systemd‑resolved: What It Brings
systemd‑resolved, shipped with systemd v246+, replaces the classic stub resolver with a local caching daemon that supports:
- Automatic DNS caching (reduces round‑trips to upstream servers).
- DNSSEC validation when enabled.
- IPv4 and IPv6 name resolution in a single stack.
- Per‑interface DNS configuration via networkd or NetworkManager.
- A single point of truth: the stub listener on
127.0.0.53forwards all queries to the configured servers.
Enabling and Configuring systemd‑resolved
- Open
/etc/systemd/resolved.confwith root privileges. - Add or modify the following lines (replace the placeholder
DNS=values with your preferred servers):# /etc/systemd/resolved.conf [Resolve] DNS=1.1.1.1 1.0.0.1 FallbackDNS=8.8.8.8 8.8.4.4 DNSSEC=yes DNSStubListener=yes - Ensure
/etc/resolv.confpoints to the stub listener. If it was a regular file, replace it with a symlink:rm -f /etc/resolv.conf ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf - Restart the service:
systemctl restart systemd-resolved - Verify the service is active:
systemctl status systemd-resolved
A Real‑World Example: Cloudflare DNSSEC
Cloudflare’s 1.1.1.1 network is DNSSEC‑enabled by default. After the configuration above, verify the setup:
# Check current status and server list
resolvectl status
# Sample output snippet
# Current DNS Server: 1.1.1.1
# DNSSEC: enabled
# Perform a query and inspect the cache flag
resolvectl query example.com
# Re‑query to see the cached response
resolvectl query example.com
# View statistics to confirm caching is happening
systemd-resolve --statistics
# Look for increased "cache hits" count
Repeated queries should show cached: yes in the query output and an increase in cache hits in the statistics.
Trade‑offs and Migration Pitfalls
- Legacy scripts: Some automation or monitoring tools parse
/etc/resolv.confdirectly. After enabling systemd‑resolved, those scripts may fail unless updated to useresolvectlor the stub symlink is preserved. - Conflicting resolvers: If
dnsmasqorunboundis also running, they may bind to127.0.0.53or53, causing port conflicts. Disable the stub listener in those services or setDNSStubListener=noin/etc/systemd/resolved.confand point the stub to the alternative resolver. - Per‑interface complexity: When using networkd, DNS settings can be overridden per interface. Ensure that the
DNS=line inresolved.confremains the default fallback.
Verify It Works
After configuration, perform the following checks:
systemctl status systemd-resolved– should showactive (running)and a listening socket on127.0.0.53:53.resolvectl status– lists the configured servers and indicates DNSSEC isenabled.- Query a known domain and observe the
cached: yesflag on the second run. - Review
systemd-resolve --statistics– cache hit/miss ratio should improve over time.
Takeaway
Switching to systemd‑resolved on RHEL 9 gives you a modern, secure DNS stack with caching and DNSSEC out of the box. The trade‑offs are mainly around legacy tooling and potential port conflicts, which can be mitigated with careful migration steps. Once enabled, use resolvectl and systemd-resolve --statistics to monitor performance and confirm that caching is active.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.