How does name resolution work on a modern Linux host, and what is 127.0.0.53?
Show the answer
Say this first
An application calls getaddrinfo in glibc, which follows the hosts: line in /etc/nsswitch.conf:
usually files (/etc/hosts) first, then DNS. DNS goes to the servers in /etc/resolv.conf. On hosts
with systemd-resolved, resolv.conf points at 127.0.0.53, a local caching stub, and the real upstream
servers are kept per interface; resolvectl status shows them. dig and nslookup read resolv.conf
directly and skip /etc/hosts; getent hosts follows the same path as applications.
Go deeper
The pieces
$ ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 39 Mar 3 10:12 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
$ grep -v '^#' /etc/resolv.conf
nameserver 127.0.0.53
options edns0 trust-ad
search corp.example.com$ resolvectl status ens192
Link 2 (ens192)
Current Scopes: DNS
Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 10.0.20.53
DNS Servers: 10.0.20.53 10.0.20.54
DNS Domain: corp.example.comThe upstream servers come from netplan, NetworkManager or DHCP. /run/systemd/resolve/resolv.conf lists
them in classic format for tools that need it.
resolv.conf rules worth knowing (glibc)
- At most 3
nameserverlines are used, tried in order. options timeout:5 attempts:2are the defaults: a dead first server costs 5 seconds per try.searchdomains are appended to names with fewer dots thanndots(default 1).
Commands
getent hosts app.corp.example.com # same path as applications, includes /etc/hosts
resolvectl query app.corp.example.com
resolvectl flush-caches
resolvectl statistics # cache hits and missesThey will ask next
ping resolves a name but dig says NXDOMAIN. How?
The name is in
/etc/hosts(or resolved by mDNS or another NSS module). ping uses NSS, dig queries DNS directly.getent hosts nameshows what applications really get.How does a VPN get its own DNS for corporate names only?
systemd-resolved supports per-link routing domains. The VPN link gets DNS servers and a domain like
~corp.example.com; queries for that domain go to the VPN's servers and everything else goes to the default link.resolvectl domain tun0 '~corp.example.com'sets it by hand.
Traps
- Editing
/etc/resolv.confby hand on a host where systemd-resolved or NetworkManager manages it. It gets overwritten or bypasses the stub. - Calling
nameserver 127.0.0.53a misconfiguration. It is the stub, and the real servers are in resolvectl.