When you’re managing a network, you may experience an occurrence of xkcd 927, where finding out which DNS server you’re using for naming resolution leads you down a rabbit hole of different programs calling each other, configuration files you can’t edit and yet aren’t centrally managed, and lots and lots of pain. In this article, I demonstrate how you can use the resolvectl command to inspect a network.

Ol’ [un]reliable

All roads lead to Rome, and all Google searches asking for DNS resolution information lead to /etc/resolv.conf. The man page for resolv.conf states: “The resolver configuration file contains information that is read by the resolver routines the first time they are invoked by a process.”

Oracle 6’s system administrator handbook says:

The man page continues on to state: “If this file does not exist, only the name server on the local machine will be queried, and the search list contains the local domain name determined from the hostname.”

Makes sense, right? Let’s see what /etc/resolv.conf contains on a modern Ubuntu 22.04 machine:

It’s not as simple as that. If you believe the man page, you’d either have a fully functional local DNS server or a non-working name resolution. Also, you might notice that /etc/resolv.conf is a symlink, and dynamically generated. This raises a question. By whom, and more importantly, from where? In /etc/resolv.conf, you see you can run resolvectl status to get more information.

Resolvectl

The man page for resolvectl says: “resolvectl may be used to resolve domain names, IPv4 and IPv6 addresses, DNS resource records and services with the systemd-resolved.service(8) resolver service.”

Indeed, resolvectl is a one-stop-shop for all of your local DNS needs. Similar to dig, for instance, resolvectl can easily fetch you the A and AAAA resource records for a domain.

Querying an IP address instead of a domain can, similar to the -x option in dig, gets you the PTR record of that IP address. The resolvectlcommand can also query MX records with the query -t MX option, resolve services and retrieve PGP and TLS keys.

But what about finding out which DNS server your machine uses when performing name resolution? If you run the command from the /etc/resolv.conf, then you can see which actual DNS servers your machine uses:

You see here that your resolv.conf mode is foreign, which means it’s managed by another package and, in this situation, the nameservers you’re getting come from the DHCP server.

Yet that creates a bit of a Catch-22. If your /etc/resolv.conf isn’t a configuration file for name resolving and is instead dynamically generated, then what configuration is it dynamically generated from?

It’s resolved (not resolve)

After much searching, your tired eyes wander around the Google searches. All of a sudden, you see it. Arch’s wiki says to edit resolved.conf (notice the “d” in “resolved”) not resolve.conf.

Yes, the way to set a static manual DNS server for your local needs is by editing /etc/systemd/resolved.conf, and specifically, preferably by adding stub files in the /etc/systemd/resolved.conf.d folder. (Yes, that’s two files with almost the same name, one completely obsolete and useless, defaulting to nothing more than a dynamically generated and symlinked “we’ve moved” banner.)

There’s another, easier, less painful way we can see why your /etc/resolv.conf says 127.0.0.1:53, and that’s seeing what’s listening on that port:

Here, you can see it’s systemd-resolve, which resolvectl uses, that listens on port 53 and handles name resolution by sending requests to the nameservers you see in resolvectl status.

Systemd-resolved

To be entirely fair, the use of the traditional /etc/resolv.conf file for configuring DNS resolution in Linux systems has not been entirely discontinued. However, the introduction of systemd-resolved, a component of the systemd init system, has provided an alternative approach to DNS configuration (refer again to xkcd 927).

The full arsenal of features of systemd-resolved are out of the scope of this article. To summarize, systemd-resolved is a system service that manages network name resolution and provides DNS caching. It’s designed to be a centralized DNS resolver for all applications running on a Linux system. Instead of relying on individual applications to handle DNS resolution, systemd-resolved takes over this responsibility, simplifying the configuration and management process.

The /etc/resolv.conf file has historically been the standard location for configuring DNS servers in Linux. However, it was prone to being overwritten by network management tools, making it challenging to maintain custom DNS server configurations. To address this issue, and provide a more consistent and reliable method for DNS configuration, systemd-resolved introduced its own configuration file: /etc/systemd/resolved.conf.

The resolved.conf file allows you to specify DNS server addresses, domain search domains, and other DNS-related options. When systemd-resolved.service starts, it reads this configuration file and dynamically generates the /run/systemd/resolve/resolv.conf file, which is then symlinked to /etc/resolv.conf. This dynamic generation ensures that the /etc/resolv.conf file always reflects the current DNS configuration defined in /etc/systemd/resolved.conf.

Here’s a quick setup of a drop-in configuration file for systemd-resolved to add another DNS server for your machine to use.

Create the /etc/systemd/resolved.conf.d folder:

Create a stub file with your DNS configuration. In this example, I’m creating a singular new DNS server and cache enabling:

Restart systemd-resolved:

Check the results using resolvectl status:

That’s it! You’ve successfully added a static DNS server to use for name resolution!

Conclusion

I think Linux gets unfairly blamed for being confusing.

Part of that, I assume, is the freedom you get. Straight out of a fresh installation, you’re free to do (and break) whatever you want with your system. There are few warnings  and, with the correct rights, no limitations. Yet there are some points in my sysadmin career in which I’ve questioned whether something couldn’t be done better, or at least less confusingly. In the case of setting up name resolution, many people asked themselves the same questions, and just as many decided to do something about it.

Configuring local DNS resolution in Linux can be a daunting task, but with the right knowledge and understanding, you can navigate the complexities with confidence. In this article, I demonstrated the traditional /etc/resolv.conf file and its limitations, as well as the introduction of systemd-resolved, a centralized DNS resolver that simplifies the configuration process.

Remember to explore the documentation and man pages for further details on specific commands and configuration options.

Happy resolving!

Author

Categories: Linux

1 Comment

Petru · 2023-07-17 at 16:42

Very interesting article. Thanks for writing it, Konstantin! 🙂

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *