DNS on Linux
Domain Name Resolution (DNS) on Linux is done through a modular system that supports historical operation as well as modern software solutions. This system can lead to frustration, as when settings seem to magically reset on startup.
Contents
Domain name resolution
Name Service Switch
The Name Service Switch (NSS) file (/etc/nsswitch.conf) defines the order of operations for various services, among them being name resolution.
A minimal configuration looks like...
hosts: files dns
This configuration will require a fully configured hosts file, as seen below.
Consider instead this configuration, which makes use of libraries and services from the systemd project. This will enable some omissions from the hosts file.
hosts: files mymachines myhostname dns
See here for more details on configuring /etc/nsswitch.
Hosts
The hosts file (/etc/hosts) is a list of addresses and names, especially for local hosts and machines. A basic hosts file looks like:
127.0.0.1 localhost
See here for more details on configuring /etc/hosts.
Resolver
The resolver configuration file (/etc/resolv.conf) is a list of nameservers to query for name resolution. The file is read sequentially for up to 3 nameservers for each lookup. As such, changes are effective immediately.
If the resolver file is being configured directly (which is rare-see below), then it should look like:
nameserver 8.8.8.8
See here for more details on configuring /etc/resolv.conf.
Multicast domain name resolution
Multicast domain name resolution (mDNS) is an expansion of the DNS protocol making use of the reserved address space. By convention, the .local domain is reserved for mDNS.
Link-local multicast name resolution
Link-local multicast name resolution (LLMNR) allows hosts to resolve names for other hosts on the same local link. Services listen on 224.0.0.252:5355 and ff02::1:3:5355.
Debugging DNS
Utilities
A number of tools exist for debugging DNS on Linux:
drill(1), used as drill NAME @SERVER TYPE
dig(1) (from the bind project, sometimes bundled with dnsutils) used as dig @SERVER NAME TYPE
resolvectl(1) (from systemd-resolved), used as resolvectl status
Programs that overwrite resolver files
dhcpcd
dhcpcd(8) is primarily a DHCP client. It will try to send DHCP information to resolvconf, but if that service is unavailable, it will itself generate /etc/resolv.conf. This latter behavior can be disabled by editing /etc/dhcpcd.conf:
nohook resolv.conf
For most use cases, it is sufficient to provide a header file (/etc/resolv.conf.head) that dhcpcd will insert at the top of the new resolver file.
openresolv
openresolv is an implementation of the resolvconf(1) protocol. This protocol describes a daemon receiving piped information from multiple sources, then orchestrating a resolver configuration. All of the following will plug into this protocol:
dhcpcd(8)
iwd(8)
NetworkManager(8)
netctl(1)
openvpn(8)
wg(8)
If the resolvconf(1) manual page redirects to resolvectl(1), then you are using systemd-resolvconf.
To disable openresolv, set resolveconf=NO in the configuration file.
See here for more details on configuring /etc/resolvconf.conf.
systemd-resolvconf
systemd-resolvconf is a compatibility layer between systemd-resolved(8) and the resolvconf(1) protocol.
If the resolvconf(1) manual page does not redirect to resolvectl(1), then you are not using systemd-resolvconf.
systemd-resolved
systemd-resolved(8) is a multi-layered application, supporting DNS (and mDNS, and LLMNR, and so on) resolution:
- a daemon handling name resolution through a dbus API, with all modern features (i.e. DNSSEC)
an NSS plugin (resolve) which re-implements most of the stack (including reading the hosts file)
- a DNS stub listener on 127.0.0.53:53
The recommended configuration of /etc/nsswitch.conf is as follows:
hosts: mymachines resolve [!UNAVAIL=return] myhostname files dns
Then, the recommendation is to link the DNS stub file (which contains just the stub listen address, 127.0.0.53) to /etc/resolv.conf.
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
On the other hand, to disable the stub listener (so as to run a different DNS server), edit /etc/systemd/resolved.conf as follows:
DNSStubListener=no
NetworkManager
NetworkManager(8) can, given certain configurations, assume that it has authority over the resolver file. To prevent overwriting of /etc/resolv.conf, pursue one of the following two configurations.
- Deactivate DNS features.
[main] dns=none
Configure the rc-manager setting.
[main] rc-manager=symlink
The rc-manager setting takes any of these values:
symlink or none means 'create /run/NetworkManager/resolv.conf and, if it is a normal file, /etc/resolv.conf'. If the resolver file is a link to any other file, it is left alone. This is the default setting.
file means 'create /etc/resolv.conf'.
resolvconf
netconfig
unmanaged
Note that, in practice, there is no standard structure to the configuration of NetworkManager. Try looking at /etc/NetworkManager/NetworkManager.conf, or in /etc/NetworkManager/conf.d/.