1. Overview

Before a computer connects to an external network resource, it must have the means of translating domain names to their respective IP addresses. Our computers get this information by default from the router upon connecting. Sometimes, we might want to configure this information by ourselves, or other times, we might want to troubleshoot this resource (DNS) when it gives us problems. In this article, we’ll discuss resolv.conf, systemd-resolve, and Avahi. Later, we’ll talk about the difference between them.

2. resolv.conf

resolv.conf is a resolver configuration file in the /etc directory that contains the nameservers that a computer will use in name resolution. That is to say, it’s used to configure the user’s computer to access the Internet DNS. Often, resolv.conf is managed by other network programs. We can edit it manually, although we should note that when we do so, the system overwrites our settings upon reboot. The resolver is a set of routines in the C library that provides access to the DNS. For instance, a process obtains network information the first time it’s invoked as the routine resolver reads this file. The resolver configuration file is human-readable and contains a list of keywords and their values. These keywords include nameserver, search, sortlist, and options. The nameserver key contains the internet addresses of the nameservers that the resolver should query. These can be either IPv4 or IPv6 addresses. The search keyword contains only the local domain name, which is determined from the local hostname returned by gethostname(2). It takes the local domain name to be everything after the first ‘.’. Further, if the hostname doesn’t contain a ‘.’, it assumes the root domain as the local domain name. Let’s see an example:

$ cat /etc/resolv.conf
nameserver 192.168.204.231
nameserver 192.168.154.6
nameserver 2c0f:fe38:2405:41a3::77

In some distros, resolv.conf is a symlink that points to /run/systemd/resolve/stub-resolv.conf. The nameserver of the local machine is used when no nameserver keyword is listed or defined in resolv.conf. When we manually edit this file, the changes are saved temporarily. When we reboot or shut down the system, or the computer detects a network change, the computer overwrites the changes (through other network programs). During installation, the OS sets two DNS parameters: timeouts and attempts. Note that the parameters are set to low values. We can manually configure resolv.conf by using any editor to edit the file. For example, let’s modify this file and add some settings:

$ vi /etc/resolv.conf

Let’s manually add a nameserver keyword with the corresponding IPv4 or IPv6 address. For this case, we’ll use Google’s public DNS address:

nameserver 8.8.8.8
nameserver 8.8.4.4

Lastly, let’s make the changes permanent by using the command resolvconf. First, we have to install resolvconf using a package manager if it’s not already on our system:

$ sudo apt-get install resolvconf

Next, we start and enable the service:

$ sudo systemctl start resolvconf.service
$ sudo systemctl enable resolveconf.service

Subsequently, let’s edit the resolvconf.d file:

$sudo vi /etc/resolvconf/resolvconf.d/head

We then add the following nameservers with their respective IP addresses and save the file:

nameserver 8.8.8.8
nameserver 8.8.4.4

3. systemd-resolve

systemd-resolve resolves domain names, IPv4 and IPv6 addresses, DNS resources, records, and services. The hostname resolution is possible through the systemd-resolved.service, which provides network name resolution to local applications via a D-Bus interface, the resolve nss-service, and a local DNS stub listener. Likewise, we can also say that systemd-resolved is a “stub resolver” because it doesn’t resolve all the names by itself but forwards the queries to a remote server if necessary. Also, it provides resolver services for DNS, including Domain Name System Security Extensions (DNSSEC) and DNS over TLS (DoT), Multicast DNS (mDNS), and Link-Local Multicast Name Resolution (LLMNR) resolver and responder. It works out of the box with a network manager using /etc/resolv.conf. systemd-resolved implements caching and validation of DNS/DNSSEC stub resolvers, LLMNR, and Multicast DNS resolvers. The caching mechanism speeds response time for the frequently used names.

3.1. Setting DNS Servers

In stub and static modes, we can manually set a custom DNS server by editing /etc/systemd/resolved.conf.d/dns_server.conf. If it doesn’t exist, we create it. Next, we add:

$ vi /etc/systemd/resolved.conf.d/dns_servers.conf
/etc/systemd/resolved.conf.d/dns_servers.conf
[Resolve]
DNS=192.168.x.x yxyx:yxyx:yxyx:yxyx 
Domain=~

If there isn’t a DNS server configured and systemd-resolved doesn’t receive DNS server addresses from the network manager, it falls back to the fallback DNS address set. This way, it ensures that DNS resolution always works:

$ vi /etc/systemd/resolved.conf.d/configured.conf
/etc/systemd/resolved.conf.d/configured.conf
[Resolve]
FallbackDNS=127.0.0.1 ::1

To disable fallback DNS functionality, we set the FallbackDNS to empty with no address (IPv4 and IPv6). Similarly, we can also configure the resolver by editing /etc/systemd/resolved.conf and then adding:

$ vi /etc/systemd/resolved.conf
[Resolve]
[Resolve]
DNS=127.0.0.1
FallbackDNS=1.0.0.1
MulticastDNS=no
DNSStubListener=no

To use this service, let’s start and enable it:

$ sudo systemctl start systemd-resolved.service
$ sudo systemctl enable systemd-resolved.service

3.2. systemd-resolved Hostname Resolution

Local applications submit network name resolution requests via several interfaces:

  • the native fully featured API system, which exposes the bus on systemd-resolved
  • the glibc getaddrinfo(3) API (this interface doesn’t disclose DNSSEC validation status information and is synchronous only)
  • a local DNS stub listener on the IP address 127.0.053 and 127.0.0.54 on the local Loopback interface

When hostname lookup is sent to multiple interfaces, the interface with the first successful response is returned. Otherwise, if it fails, the response from the last interface is returned. The per-interface routing domains (search and route-only) and global search domains determine the routing of lookup. To provide domain name resolution for programs that read /etc/resolv.conf directly, systemd-resolved has four different modes for handling the file: stub, static, uplink, and foreign. The stub mode, whose file is located at /run/systemd/resolve/stub-resolv.conf, is the recommended mode, so we should use it. This is because it contains the local stub 127.0.0.53 as the only DNS server and list of search domains. Since it is the recommended mode of operation, it propagates the systemd-resolved to manage configuration for all clients. To use it, we replace the /etc/resolv.conf with a symbolic link. If we’ve installed Avahi, we’ll disable or mask the avahi-daemon.service and avahi-daemon.socket to prevent conflicts with systemd-resolved.

4. Avahi

Avahi is a free Linux service that runs on the client machines to perform a network-based, zero-configuration networking implementation. It facilitates service discovery on the local network via mDNS/DNS-SD. Further, it allows programs to print and discover services and hosts running on a local network without requiring specific configurations. That is, it enables us to plug our devices (computers, printers, and more) into the network and instantly view the other available devices and services. Avahi enables people on the network to chat and find shared files. The primary interface Avahi uses is a D-Bus. Zeroconf’s main tasks are automatic assignment of numeric network addresses, automatic distribution and resolution of hostnames, and lastly, location of other network devices.

4.1. Installing and Enabling Avahi

We can install Avahi by installing the avahi-daemon package:

$ sudo apt install avahi-daemon

We should keep in mind that systemd-resolved has a built-in mDNS service. Most importantly, before using Avahi, we should disable the systemd-resolved multicast DNS resolver/responder or entirely disable the systemd-resolved.service. After we have installed it, we start/enable it by running the init script or by using the systemctl commands:

$ /etc/init.d/avahi-daemon start
$ sudo systemctl start avahi-daemon.service
$ sudo systemctl enable avahi-daemon.service

We can stop/disable the service when we run one of:

$ /etc/init.d/avahi-daemon.service stop
$ sudo systemctl disable avahi-daemon.service

4.2. Avahi Hostname Resolution

Avahi provides local hostname resolution via the “hostname.local” naming scheme. It requires the nss-mdns package. Therefore, we should install and enable it if it isn’t there. The avahi-daemon.service should also be running. We should keep in mind that Avahi requires root privilege. The local network we’re using should also be secure. Also, we should set the firewall to permit multicast traffic on port 5353. The mDNS domain “.local” is where hosts on the network reside, and mdns4_minimal handles queries only for that domain. Host name resolution takes place automatically if we issue commands such as:

$ ssh hostname.local
$ nmap hostname.local

To resolve a hostname to an IPv4 address using avahi-resolve, we can run:

$ avahi-resolve -n -4 hostname.local

And, for reverse lookup, we run:

$ avahi-resolve -a 192.168.x.x

Avahi-resolve does not utilize the NSS functionality of libniss-mdns. Instead, it obtains an IP address/hostname directly from the mDNS multicast. Importantly, Avahi includes several utilities that help us discover the services running on the network. We can also use the XML service definition placed at /etc/avahi/service to publish a service. For instance, some of the Avahi commands are:

$ avahi-browse --all
$ avahi-browse --ignore-local
$ avahi-browse --resolve 
$ avahi-browse --terminate

4.3. Avahi Services

The Avahi zeroconf browser will show the various services on our network. Further, we can browse SSH and VNC servers using bssh and bvnc, respectively. Avahi advertises the *.service files found in /etc/avahi/service. Besides, the Avahi user/group should be able to read files in this directory. We can easily create our own if we want to advertise a service without the *.service file. Let’s look at an example of an Avahi file that advertises a regular FTP server – vsftpd:

/etc/avahi/services/ftp.service
<?XML version="1.0" standalone=’no’?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name>FTP file sharing</name>
<service>
<type>_ftp._tcp</type>
<port>21</port>
</service>
</service-group>

This file allows Avahi to advertise the FTP server. As a result, we should be able to find the FTP server from a file manager on another computer within our network. We also need to enable hostname resolution on the client.

5. Differences Between resolve.conf, systemd-resolve, and Avahi

Let’s summarize the differences between these services and their configuration files:

resolv.conf

systemd-resolve

Avahi

Used to configure and store information about DNS servers

Provides network name resolution to the local applications via resolve NSS-service and a local stub listener on 127.0.0.53

Resolves IP addresses/hostname directly from mDNS multicast without requiring the NSS functionality of libnss

Only contains the nameservers defined – it does not advertise them

Does not publish any service

Publishes services set up on the local machine according to the *.service files located in the /etc/avahi/services directory

DNS requests are sent to the first nameserver listed. If it fails, it is sent to the second or third nameserver.

Supports split DNS. The system sends DNS requests to the first nameserver listed in /etc/resolv.conf where it splits DNS requests according to DNS routing domains.

Provides local hostname resolution through the “hostname.local” naming scheme

Network programs update the information in resolv.conf frequently. In addition, we can also manually edit the file using resolvconf.

Relies on the network manager to provide nameservers, whereas in other systems, /etc/resolv.conf is symlinked to /run/systemd/resolve/stub-resolv.conf, which is then used to list the nameservers

Depends on the resolv.conf to obtain the nameserver information, which it then uses for name resolution

6. Conclusion

In this article, we’ve discussed resolv.conf, systemd-resolve (systemd-resolved), and Avahi. We’ve mentioned how these work and identified the interdependent ones. Above all, we should remember that sytemd-resolved cannot work together with Avahi, and only one can be installed simultaneously**. Depending on the scope of our network, we can always choose the service that satisfies the need of that particular network. Lastly, we can configure our nameservers in the resolv.conf file.