Debian DNS: systemd-resolved vs resolvconf

Debian's approach to Domain Name System (DNS) resolution has evolved from static text configurations and script-based aggregators like resolvconf to daemon-driven local caching resolvers like systemd-resolved. This article examines how Debian handles DNS queries under both frameworks, compares their core architectures, caching, and security features, and explains how to configure or switch between them on modern Debian installations.

The Traditional Approach: resolvconf and /etc/resolv.conf

Traditionally, Linux networking relies directly on the /etc/resolv.conf configuration file, which the C library resolver (glibc) reads to determine which nameservers to query. In simple setups, this file is written statically by the system administrator.

However, modern systems often run multiple network management tools—such as DHCP clients, PPP daemons, VPN clients, and ifupdown—that simultaneously attempt to overwrite /etc/resolv.conf. The resolvconf framework was designed to resolve this contention.

  • How it works: resolvconf acts as an intermediary. Network configuration scripts register their DNS requirements by running the resolvconf executable. The resolvconf daemon aggregates these inputs according to predefined priority rules and dynamically rewrites /etc/resolv.conf.
  • Stateless Forwarding: Traditional resolvconf does not cache DNS records or run a local DNS service. It simply populates standard upstream IP addresses into /etc/resolv.conf.
  • Limitations: Because it lacks local caching, every DNS query generated by an application must travel over the network unless an external caching daemon like dnsmasq or unbound is manually installed. Additionally, it lacks native support for advanced protocols like DNSSEC validation and DNS-over-TLS (DoT).

The Modern Alternative: systemd-resolved

Starting with Debian 12 (Bookworm), systemd-resolved was split into a separate, optional package rather than being installed automatically with the core systemd package. Unlike resolvconf, systemd-resolved is an active network service that runs a local DNS stub listener.

  • How it works: systemd-resolved binds a local caching resolver to the loopback IP 127.0.0.53 on port 53. Debian's /etc/resolv.conf is replaced with a symbolic link pointing to /run/systemd/resolve/stub-resolv.conf, which points applications to 127.0.0.53.
  • Integrated Caching and Features: It features a built-in cryptographic validation engine for DNSSEC, support for DNS-over-TLS (DoT), Link-Local Multicast Name Resolution (LLMNR), and Multicast DNS (mDNS).
  • Per-Interface Routing: systemd-resolved can route queries based on domain routing rules across multiple interfaces. For example, queries for an internal corporate domain can be directed over a VPN tunnel interface, while public queries go out through the default gateway.

Key Architectural Differences

Feature resolvconf systemd-resolved
Local Caching No (requires third-party daemon) Yes (built-in)
Configuration Model Shell scripts updating static files D-Bus daemon and resolvectl CLI
Loopback Stub No (/etc/resolv.conf contains external IPs) Yes (uses 127.0.0.53)
Split-DNS / VPN Routing Limited (requires custom hooks) Native (per-link DNS routing)
Modern Protocols None (standard DNS only) DNSSEC, DoT, mDNS, LLMNR

Managing and Switching Implementations on Debian

Debian allows administrators to choose which mechanism manages name resolution based on the system's requirements.

Using Traditional resolvconf

To use the traditional framework, install the package:

sudo apt update
sudo apt install resolvconf

Once installed, interfaces defined in /etc/network/interfaces can define nameservers using the dns-nameservers directive:

iface eth0 inet dhcp
    dns-nameservers 1.1.1.1 8.8.8.8
    dns-search example.com

Using systemd-resolved

To switch to systemd-resolved, install the package and link the stub file:

sudo apt update
sudo apt install systemd-resolved
sudo systemctl enable --now systemd-resolved
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

You can view current DNS settings, query statistics, and per-link configurations using the management utility:

resolvectl status

To revert back to a standard configuration, disable the service, remove the package, and restore /etc/resolv.conf as a standard text file or symlink it back to the state managed by resolvconf or your active network manager.