DNS set to systemd's 127.0.0.53 - how to change permanently?

I've recently upgraded to 17.10. When I try to browse to a website, or ping a domain it fails saying the site cannot be resolved.

network-admin shows the contents of /etc/resolv.conf to be nameserver: 127.0.0.53

If I change that to 8.8.8.8 or 208.67.222.222 then everything works. Until I reboot.

Upon reboot or resume, the nameserver is reset to 127.0.0.53.

How do I permanently set the nameserver to something that works?


For systemd fans, if I run systemd-resolve --status I get

Link 3 (wlo1)
      Current Scopes: LLMNR/IPv4 LLMNR/IPv6
       LLMNR setting: yes
MulticastDNS setting: no
      DNSSEC setting: no
    DNSSEC supported: no

If I follow the advice at this question - DNS keeps resetting after reboot. Ubuntu 17.10 - DNS still fails to resolve.


Solution 1:

You can install a package resolvconf, which will modify the way /etc/resolv.conf is built up at system boot.

sudo apt install resolvconf

You can then create or modify a file /etc/resolvconf/resolv.conf.d/tail. If you put in this file a line nameserver 8.8.8.8, this line will be added at the end of /run/resolvconf/resolv.conf at boot. /etc/resolv.conf will now be a symbolic link to this file.

Post Scriptum:

Almost two years after posting my answer I came across https://bugs.launchpad.net/ubuntu/+source/ppp/+bug/1778946 which explains exactly why merely installing resolvconf solved a dns problem I had at the time. I feel I have to share this here.

Although my answer addresses the question in a proper way, indeed a warning should be added that, if you want/need to do this, probably something else is wrong. This was already stated by @intelfx at the time, 127.0.0.53 should work by itself.

According that bug report, after a pptp VPN goes down, resolv.conf is restored with the wrong access rights. ping ubuntu.com does not work, sudo ping ubuntu.com does. Installing resolvconf solved it, because it takes over resolv.conf, restoring it with correct rights. Changing systemd-resolve settings is no solution in this case, since the bug is in ppp. But an alternative, maybe simpler solution is sudo chmod a+r /etc/resolv.conf after VPN down. And this can be automated by putting an executable script in /etc/NetworkManager/dispatcher.d with contents:

#!/bin/sh
if [[ "$1"="ppp0" && "$2"="vpn-down" ]]; then  
    /bin/chmod a+r /etc/resolv.conf
fi

In all cases the contents of resolv.conf do not change. And, yes, I know pptp must be avoided because of security issues, but at the time I thought of it as a good excercise for an ubuntu newbie. I imagined it would work out of the box. Little did I know that it would give me a headache, as diagnosed so well by @intelfx.

Solution 2:

The correct solution would be to fix systemd-resolved instead of trying to cure migraine with a guillotine.

It is a nice tool, really, if used properly.

Judging by your systemd-resolve --status output...

Link 3 (wlo1)
      Current Scopes: LLMNR/IPv4 LLMNR/IPv6
       LLMNR setting: yes
MulticastDNS setting: no
      DNSSEC setting: no
    DNSSEC supported: no

...your network manager tool does not communicate per-interface DNS configuration to systemd-resolved.

Recent versions of NetworkManager will detect if /etc/resolv.conf is a symlink to a resolved-generated file (/run/systemd/resolve/*.conf or /usr/lib/systemd/resolv.conf) and if that's the case, communicate with resolved directly.

Alternatively, recent versions of systemd-resolved try to be compatible with the historical resolvconf interface by installing a resolvconf binary that does the right thing.

While either of these two solutions would be preferred, if you are looking for a quick and dirty fix, you can just configure systemd-resolved to use your DNS servers globally:

$ cat /etc/systemd/resolved.conf
<...>
[Resolve]
DNS=8.8.8.8 8.8.4.4
<...>

Then restart systemd-resolved.service or reboot.

Solution 3:

working within the systemd paradigm add a DNS to a link / device

  • systemd.network manual page

using ubuntu 17.10+ add a *.network file:

sudo nano /lib/systemd/network/100-somecustom.network:

100-somecustom.network ( 100 can be any number for priority, and it requires the .network file extension ):

[Match]
Name=wlo1 # the device name here

[Network] # add multiple DNS 
DNS=8.8.8.8
DNS=208.67.222.222

Then restart:

sudo service systemd-networkd restart

Also look into:

netplan apply

Then check:

systemd-resolve --status wlo1

From info page info systemd.network :

In addition to /etc/systemd/network, drop-in ".d" directories can be placed in /lib/systemd/network or /run/systemd/network directories. Drop-in files in /etc take precedence over those in /run which in turn take precedence over those in /lib. Drop-in files under any of these directories take precedence over the main netdev file wherever located. (Of course, since /run is temporary and /usr/lib is for vendors, it is unlikely drop-ins should be used in either of those places.)

Another approach disable the DNSStubListener for usage with dnsmasq:

sudo nano /etc/systemd/resolved.conf:

#
DNSStubListener=false

related:

  • https://superuser.com/questions/1153203/ubuntu-17-04-systemd-resolved-dns-lookups-randomly-fail
  • DNS at systemd's 127.0.0.53 is ignoring some lookups
  • https://unix.stackexchange.com/questions/304050/how-to-avoid-conflicts-between-dnsmasq-and-systemd-resolved
  • https://moss.sh/name-resolution-issue-systemd-resolved/