This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
DNSSEC support in stub-resolver
- From: Petr Spacek <pspacek at redhat dot com>
- To: libc-alpha at sourceware dot org
- Date: Mon, 28 Apr 2014 13:56:37 +0200
- Subject: DNSSEC support in stub-resolver
- Authentication-results: sourceware.org; auth=none
Hello list,
IETF mailing list dedicated to DNS-DANE hosted a lengthy discussion [0] about
DNSSEC support in stub-resolvers.
The questions are mostly:
- How can we enable applications to use DNSSEC easily *and securely*?
- How can we make DNSSEC related configuration system-wide? (I.e. the intent
is to *avoid* adding application-specific switches to all applications dealing
with DNS.)
Summary
=======
This is rephrased version of original summary from DANE-list [1].
The problem is how to determine that answer from DNS can be trusted.
Full recursive resolvers can do DNSSEC validation and indicate result of the
validation via Authenticated Data (AD) bit in DNS header.
Stub-resolvers often communicate with recursive-resolvers via insecure
channels so no data in DNS packet can be trusted.
For this reason, applications have a special switch for dis/trusting replies
obtained via stub-resolver. Famous example is VerifyHostKeyDNS option in
OpenSSH client.
Practically, it means that administrator has to flip a switch in all
DNSSEC-enabled applications when validating recursive resolver is un/installed
or channel to the resolver is dis/trusted.
This is not an optimal situation and it has potential to create administrative
nightmare as number of DNSSEC-enabled applications grows.
This proposal calls for system-wide configuration for dis/trusting recursive
resolver (and channel to the resolver) and API for obtaining secured answers.
The discussion on DANE list was focused on the principle of configuring trust
in stub-resolver, we didn't discuss API extensions etc.
Now, I would like to start discussion about potential extensions to libresolv
API & configuration.
*This is first and raw draft, any suggestions are more than welcome!*
Configuration
=============
Basic assumption is that only administrator knows if recursive resolver and
communication channel are trusted for DNSSEC validation or not.
(E.g. Unbound vs. old dnsmasq ; IPSec vs. plain IP considerations.)
This trust must be expressed somehow.
If we consider machines using DHCP(d), it seems that we need to have
per-resolver configuration.
dhcpclient will mess with /etc/resolv.conf as usual, so global switch like
"resolver-trusted=true" could be dangerous. Imagine a case where admin
installed local resolver, turned it on and then moved to another network.
Dhcpclient rewrote nameserver lines in /etc/resolv.conf. In that case the
system is vulnerable!
This reasoning leads to the question:
How can we handle per-resolver options?
Examples (in no particular order; all names are random):
1) Extend nameserver line in /etc/resolv.conf
nameserver 127.0.0.1 trusted=true
nameserver 192.0.2.1 # default is trusted=false
I'm afraid that this will not work. I expect many programs parsing
/etc/resolv.conf and expecting the "classical" format ...
2) Put per-resolver configuration to a separate (optional!) file
E.g. /etc/resolv.ext (propose your own name)
nameserver 127.0.0.1 trusted=true
It seems a bit weird but maybe it is the cleanest option we have...
3) Extend option syntax in /etc/resolv.conf
options trusted:127.0.0.1
I have no idea how in/compatible this change can be.
4) Add a new verb to /etc/resolv.conf
trusted-nameservers 127.0.0.1 192.0.2.1 2001:DB8::1234
Which option do you like? Propose your own!
API extensions
==============
This proposal adds few new flags. No functions will change their behavior if
those flags are not present.
Applications need to have ability to find out if the flag is supported or not.
E.g. simply calling getnameinfo() with the new flag is fine if it returns an
error on systems with an older library.
Assumption: DNS answer is deemed secure if it arrived from trusted-resolver
(configured above) and has AD bit set in the DNS header.
Again:
*This is first and raw draft, any suggestions are more than welcome!*
1) getnameinfo/getaddrinfo
Goal: Enable secure name-address-name translations chains like *FQDN* -> IP ->
canonical FQDN resolution.
- Add flags AI_SECURE_ONLY and NI_SECURE_ONLY (or something like that)
- Use (RES_NOALIASES & RES_USE_DNSSEC)
- Do not use (RES_DNSRCH & RES_DEFNAMES)
- Return answer only if result is deemed to be secure
- Return EAI_INSECURE if an answer was received but is not deemed secure
- Return other EAI_* errors as usual
2) res_* interface
Goal: Get data associated with given *FQDN* and make sure that nobody tampered
with it.
- Add new flag RES_SECURE_ONLY to _res.options
- All res_* functions should fail if RES_SECURE_ONLY is set but
-- any of (RES_DNSRCH & RES_DEFNAMES) is set
-- any of (RES_NOALIASES & RES_USE_DNSSEC) is not set
res_send() and derivatives
- Return answer only if result is deemed to be secure
- Return error if an answer was received but is not deemed secure
res_search()
- doesn't support RES_SECURE_ONLY: RES_SECURE_ONLY exact match on FQDN
How can application detect that RES_SECURE_ONLY is supported?
Thank you for your time!
[0] http://www.ietf.org/mail-archive/web/dane/current/msg06469.html
[1] http://www.ietf.org/mail-archive/web/dane/current/msg06658.html
[2] man ssh_config from
--
Petr Spacek @ Red Hat