Local DNS resolver on all Ubuntu installs

Registered by Martin Pitt on 2016-05-05

On desktop/touch, NetworkManager runs a local dnsmasq instance as a DNS resolver, which handles failover between multiple DNS servers.

On Ubuntu server and cloud instances there is no such thing: DNS servers (via DHCP responses) get written to /etc/resolv.conf (via resolvconf, though) and glibc does the DNS resolution by itself. If the first DNS server fails, *every* DNS resolution will suffer from a ~ 10 second timeout.

A local resolver such as dnsmasq or resolved keeps track of broken DNS servers and uses a better load balancing on them, plus provides local DNS caching. The goal of this blueprint is to provide an unified local DNS resolver on all Ubuntu installations.

Blueprint information

Status:
Complete
Approver:
Steve Langasek
Priority:
Undefined
Drafter:
Martin Pitt
Direction:
Needs approval
Assignee:
Martin Pitt
Definition:
Review
Series goal:
Accepted for yakkety
Implementation:
Implemented
Milestone target:
milestone icon ubuntu-16.07
Started by
Martin Pitt on 2016-05-30
Completed by
Martin Pitt on 2017-10-25

Whiteboard

dnsmasq:
 + tried and tested on the desktop
 + very small and lightweight
 - updating servers needs to happen over D-Bus (which might not be installed/wanted on servers or cloud instances) or program restarts (which temporarily breaks DNS resolution)
 - hard to see the actual DNS servers being used (/etc/resolv.conf says 127.0.0.1) (requirement from kiko)

resolved:
 - not used in (Ubuntu) production yet
 + also very small and lightweight (already installed in ≥ wily)
 + can be updated via D-Bus or files in /run, thus does not require dbus installed
 + can keep /etc/resolv.conf file or resolvconf symlink with the "real" DNS servers for admins to look at
 + can do DNSSEC
 * includes the resolvconf "dynamic resolv.conf" functionality, but also works together with resolvconf; a lot of packages currently integrate with resolvconf, see http://people.canonical.com/~pitti/tmp/resolvconf-hooks.txt -- if we want to move, this will be a separate BP

There are of course other options like bind, but they have a much bigger footprint, need configuration, and the vast majority of VMs, containers, desktops, touch, and even servers won't need all fully fledged DNS server, they just need a caching resolver (i. e. similar to nscd).

As it is very early in the cycle, Christian and I propose to use resolved. If that causes too many problems, we can move to dnsmasq and need to re-discuss how to put the "real" DNS servers into resolv.conf.

NetworkManager
--------------------------
Ideally NetworkManager would grow a DNS plugin, like it already has for dnsmasq and unbound. This is somewhere on the horizon, but in the meantime we can just have dhclient update the DNS servers. This needs to work anyway, and NM is just calling dhclient.
-- NM now got a resolved plugin: https://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?id=818023c

Dropping dnsmasq in favor of resolved will provide easy introspection of what the actual name servers are, as they will then appear in /etc/resolv.conf (regardless of whether that's a file or a symlink to resolvconf or resolved generated files).

dhclient
------------
If /etc/resolv.conf is not a symlink to /run/systemd/resolve/resolv.conf, dhclient updates that with nameservers picked up from DHCP, either directly (if /etc/resolv.conf is a file) or via resolvconf. resolved reacts to changes of resolv.conf and updates its DNS server list from that.

Thus no changes are required in that area.

Resolving
--------------
Of course then glibc should not use /etc/resolv.conf directly; resolved provides a corresponding NSS module (libnss-resolve) which queries resolved, and falls back to the usual "dns" (i. e. /etc/resolv.conf) if that is unavailable for some reason. Thus installing libnss-resolve needs to insert "resolve" before "dns" in nsswitch.conf (the postinst/postrm already do that in xenial).

Bugs: https://bugs.launchpad.net/ubuntu/+bugs?field.tag=resolved

(?)

Work Items

Work items:
libnss-resolve: Enable systemd-resolved on install, disable it on removal: DONE
seed libnss-resolve: DONE
once resolved grows DNS server, enable that (127.0.0.53:53): DONE
(optional): enable DNSSEC during the development cycle, announce it to watch for corner cases where it breaks (there are some known-broken cases): DONE
announce to u-devel@: DONE

Work items for ubuntu-16.06:
Provide an option to disable resolved DNS caching (https://github.com/systemd/systemd/pull/3592): DONE
check if libnss-resolve includes libnss-mdns4 functionality (not yet; it fully implements LLMNR, but not (yet) MDNS): DONE

Work items for ubuntu-16.09:
Decide whether or not we want caching by default (low privacy issue vs. efficiency), and where (no answer/complaint -- let's keep it): DONE

Work items for ubuntu-16.10:
[pitti] Disable DNSSEC in resolved for final release: DONE

Work items for ubuntu-16.12:
Backport/enable NetworkManager resolved DNS plugin (waiting for NM 1.4 to land): DONE
drop launching dnsmasq from NetworkManager (needs NM resolved DNS plugin to function properly): DONE
[vorlon] add comment to /etc/resolv.conf (via resolvconf /head) where to see real name servers (#1638836) (should switch NM to resolved first): DONE

This blueprint contains Public information 
Everyone can see this information.