Should /etc/resolv.conf be a symlink?

On my Fedora 32 system, /etc/resolv.conf is a file, not a symlink, created by NetworkManager, and identical to /var/run/NetworkManager/resolv.conf.

I tried a VPN client (Windscribe) which complains with

/etc/resolv.conf is not a symlink, this may break DNS

and fails.

What is likely at fault? Is /etc/resolv.conf supposed to be a symlink?


It depends.
As far as I know, it is not by default on Fedora 32, but you can replace it with a symlink.
Actually, there are multiple ways how to manage it and which resolver the system should rely on:

1 Like

What would be the proper “Fedora way”?

I’ve seen suggestions to replace it with a symlink to /var/run/NetworkManager/resolv.conf or the one from systemd. I just don’t want to cause myself headaches, especially with networking.

The current Fedora way is to use /etc/resolv.conf as a plain text file managed by NetworkManager.

The proper way is not really limited to a single way.
Any way can be considered proper as long as it helps its users achieve their goals in accordance with the documentation and distribution-specific policies if any.

Personally, my current resolver configuration is based on the following approach:

sudo mkdir -p /etc/systemd/resolved.conf.d
sudo tee /etc/systemd/resolved.conf.d/00-custom.conf << EOF
sudo systemctl --now enable systemd-resolved.service
sudo ln -f -r -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
sudo sed -i -e "/^hosts:/s/\s.*$/ files resolve myhostname/" /etc/nsswitch.conf

It is not the default Fedora way, but it is proper enough to solve my tasks.

So, even the Fedora way will change in the next release.


Just a quick note: systemd-resolved will be the Fedora way :slight_smile: in the upcoming Fedora 33 release:


Looks like systemd-resolved is the way to go moving forward.

Are there downsides or compatibility issues with setting DNSOverTLS=yes?

In /etc/nsswitch.conf, adding resolve to the hosts line makes sense to use systemd-resolved, but the wiki indicates resolve [!UNAVAIL=return].

More generally, what “should” the hosts line look like? Mine is:

hosts: files mdns4_minimal [NOTFOUND=return] dns myhostname

as in this Fedora blog article

Aside from wondering if this line could be the source of my (other) samba/windows network/printer visibility issues, I’m confused by the [STATUS=ACTION] line.

The blog states:

Notice the commands mdns4_minimal [NOTFOUND=return]. They tell your system to use the multicast DNS resolver to resolve a hostname to an IP address. Even if that service works, the remaining services are tried if the name doesn’t resolve.

What I understand from this explanation is that if the preceding service succeeds but finds no result, the system should try the subsequent services.

This is bizarre to me since “return” in programming means to quit that function, and also because I would think this specification would be necessary after each service if this description is true.

In contrast the man page says:

Optional actions to perform if a particular result is obtained from the preceding service, e.g., “[NOTFOUND=return]”.


Return a result now. Do not call any further lookup functions.

If I understand correctly, any services following [NOTFOUND=return] are not used if, eg. ndns4_minimal does not find a result. Why would anything be listed after this option anyway?


  • It will not work if you rely solely on local unencrypted resolvers provided by DHCP.
  • It may not pass through some corporate and totalitarian government firewalls and DPIs.

I use nss-resolve for mDNS, LLMNR and DNS.
So, using nss-mdns is pointless as it just adds redundant latency.

It should return a result if the reply is success, or notfound, or tryagain.
I.e. it overrides the default continue action for notfound and tryagain as the default for success is return anyways.
I don’t really need it, because I use nss-resolve to avoid DNS leaks and in my case nss-myhostname is enough for minimal fault tolerance.

This only overrides the default continue action for notfound.
It’s still possible to continue with unavail or tryagain.

Also note that nss-mdns resolves only *.local domains, you still need to continue otherwise.

1 Like

Hmm lots to learn. Thanks for the details.

Also, what is the difference between having /etc/resolv.conf be a symlink to /run/systemd/resolve/stub-resolv.conf or /run/systemd/resolve/resolv.conf? I’ve seen both targets suggested.

==> /run/systemd/resolve/stub-resolv.conf <==
# This is a dynamic resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists all
# configured search domains.

==> /run/systemd/resolve/resolv.conf <==
# This is a dynamic resolv.conf file for connecting local clients directly to
# all known uplink DNS servers. This file lists all configured search domains.

I already read those comments before asking, but I don’t really understand. “internal DNS stub resolver” vs “uplink DNS servers” … In practical terms, what does it mean?

==> /run/systemd/resolve/stub-resolv.conf <==
options edns0 trust-ad

==> /run/systemd/resolve/resolv.conf <==
nameserver 2001:4860:4860::8888
nameserver 2001:4860:4860::8844

Most applications should use functions like getaddrinfo() to resolve domain names.
This way relies on the NSS libraries in accordance with /etc/nsswitch.conf.

However, some applications may still use /etc/resolv.conf to get resolvers or search domains.
E.g. nslookup fetches the default resolver if it is not specified explicitly.

Moreover, the apps like nslookup can use only plain unencrypted DNS.
They do not support split-DNS or DNS-over-TLS by themselves.
That’s why, you need to create the proper symlink to the stub resolver to make those features work for nslookup and the like by default.

In fact, it’s best to avoid using nslookup in favor of modern tools:

resolvectl query

Another reason for using stub resolver is to make its features work for nss-dns.
But there’s no much point as you can just replace nss-dns with nss-resolve.

1 Like

I’m sure this is useful information, but I’m just not familiar with getaddrinfo(), nslookup, nss-dns, nss-resolve, etc.

It sounds like /run/systemd/resolve/stub-resolv.conf is the more recommended approach, though I don’t know the consequences or downsides of not using /run/systemd/resolve/resolv.conf. Clearly they are both provided. As for why, and when each is pefered, it remains a mystery to me.

To summarize, it seems:

  • /etc/resolv.conf should be a symlink, especially moving forward.
  • The symlink should probably point to /run/systemd/resolve/stub-resolv.conf.
  • The line containing hosts in /etc/nsswitch.conf should be updated to include resolve.

For the latter point, the elements and order have important implications on functionality, which also mystify me, but perhaps should be left to another question.

When an application wants to resolve a domain name, it typically calls getaddrinfo() from glibc.
The query is then processed in the order defined in /etc/nsswitch.conf by the following NSS libraries:

> ls -1 /usr/lib*/libnss_*

The prefix nss- is used to specify the context and it is omitted in /etc/nsswitch.conf:

  • nss-resolve relies on systemd-resolved, which makes /etc/resolv.conf virtually obsolete.
  • nss-dns relies on /etc/resolv.conf and can be replaced with nss-resolve.

The apps like nslookup do not use getaddrinfo(), but utilize /etc/resolv.conf directly.
To be able to use split-DNS or DNS-over-TLS for these apps, you need the systemd-resolved stub resolver in /etc/resolv.conf.

Actually, it is not really important whether /etc/resolv.conf is a symlink or not.
What is important is its content, but only for those apps that do not use getaddrinfo(), or when nss-dns is not replaced with nss-resolve.