[dns-operations] DNS at FOSDEM 2016
edmonds at mycre.ws
Wed Feb 3 18:41:45 UTC 2016
Shane Kerr wrote:
> At 2016-02-03 14:14:00 +0100
> "Ralf Weber" <dns at fl1ger.de> wrote:
> > DNS requests and HTTP request are two totally different beasts wrt
> > scaling, operation and cost. Also the current authoritative
> > infrastructure we have today would not scale to resolvers on all
> > clients. The OS having an resolver is a great idea until it has a
> > problem, which may be the reason that a lot of OS vendors so far haven't
> > done it. I do hope that the systemd people offer an option not to use
> > it.
> My understanding is that the systemd resolver is not a full-service
> resolver, but rather just forwards queries to the local caching
> resolver. It does cache locally and perform validation though, so
> does bring benefit.
This is correct, systemd-resolved is a replacement for the Linux *stub*
resolver, which consists of libnss_dns, libresolv, and (optionally)
nscd, though nscd caches more than just NSS 'hosts' lookups. Parts of
this code are descended from the 'libresolv' parts of the 'libbind' DNS
client distributed with BIND4/BIND8. It was originally imported into
glibc from BIND 4.9.1 in May 1993, and updates were periodically
imported until the last update from BIND 8.2.3-T5B in July 2000.
('libbind' continued to be appended to the BIND9 distribution until BIND
9.6.0, when it was split out into a separate standalone distribution and
arbitrarily given its own version number 6.0. Later it was adopted by
Jeremy Reed under the NetBSD umbrella and renamed "netresolv".)
I'm confused at the comments in other parts of the thread about BIND and
Unbound already existing, which are not stub resolvers. Probably
BIND9's lwresd when combined with nss-lwres would qualify as a stub
resolver, but I believe the nss-lwres component isn't part of BIND9 but
rather a third party developer's (unmaintained?) project. Unbound ships
a library-ized version of itself called libunbound which could be used
to construct a stub resolver. I tried to do that once (Google for
'nss-ubdns') but abandoned the approach when I realized that loading
libunbound and thus OpenSSL into every process doing getaddrinfo() or
equivalent was pretty crazy/crashy. I came to the conclusion that you
would want to split the stub resolver so that the crypto operations can
be done in an isolated process, which incidentally appears to be the
exact split the systemd developers have arrived at in their
systemd-resolved / nss-resolve split. (The two components communicate
locally over the D-Bus protocol.)
Basically, the suggestion "why not just use a local BIND/Unbound/etc. to
validate" leaves unspoken the qualification "...along with the existing
libbind-descended non-validating stub resolver (and hope that
/etc/resolv.conf always points to your local BIND/Unbound instance)".
That stub resolver code is old, difficult to maintain, and has a not
unblemished security history. E.g., the big one for libresolv was this
vulnerability, from the first few years of the 21st century, which
affected a number of OSes, including Mac OS X, Solaris, and GNU/Linux:
"The BIND 4 resolver library (libresolv.a) contains several buffer
overflows in the functions that handle responses for network name
and address requests (getnetbyname(), getnetbyaddr()). While
reading the answer portion of a DNS response, the functions copy
data received from the network into inadequately sized buffers. A
specially crafted DNS response could overflow the buffers, possibly
injecting arbitrary code onto the stack."
There have been some close misses recently in code descended from this
software, for instance an incorrect bug fix in 2007  introduced a
buffer overflow that wasn't discovered until 2015 . Thankfully,
exploitation required conditions in calling code that were unlikely to
occur in practice, but this was only verified through extensive source
code analysis and testing:
"This can only happen if these functions are called with a
misaligned buffer. I looked at quite a bit of source code, and
tested applications with a patched glibc that logs misaligned
buffers. I did not observe any such misaligned buffers."
"Bug 4381 - unaligned memory access in gethostbyname_r()"
and corresponding code commit:
"Bug 18287 (CVE-2015-1781) - Buffer overflow in getanswer_r,
and corresponding code commit:
Diversity in DNS server implementations seems to be well-tolerated, even
celebrated, so I'm confused as to why development of a validating stub
resolver in daemon form and a corresponding Name Service Switch module
(the existence of which are a lot rarer than DNS servers) is bringing up
arguments about having "too much" code diversity.
If there's a criticism about code diversity in this general area, it's
probably to be made about the Name Service Switch itself. If I
understand correctly, there isn't one Name Service Switch interface, but
one for each operating system, based on documentation from earlier,
proprietary implementations. E.g., from the GNU libc manual:
It is designed after a method used by Sun Microsystems in the C
library of Solaris 2. The GNU C Library follows their name and calls
this scheme Name Service Switch (NSS).
Though the interface might be similar to Sun’s version there is no
common code. We never saw any source code of Sun’s implementation
and so the internal interface is incompatible.
And from the FreeBSD nsswitch.conf(5) manpage:
The nsswitch.conf file format first appeared in FreeBSD 5.0.
It was imported from the NetBSD Project, where it appeared
first in NetBSD 1.4.
Luke Mewburn <lukem at netbsd.org> wrote this freely distributable
name-service switch implementation, using ideas from the ULTRIX
svc.conf(5) and Solaris nsswitch.conf(4) manual pages.
That makes it difficult to write a portable NSS module, effectively you
might end up having to write a separate implementation for each OS whose
Name Service Switch you want to target.
More information about the dns-operations