New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: validate DNSSEC in Go's DNS resolver #13279

Open
bradfitz opened this Issue Nov 16, 2015 · 6 comments

Comments

Projects
None yet
5 participants
@bradfitz
Member

bradfitz commented Nov 16, 2015

DNSSEC is being deployed.

We should support it eventually.

@mwwaters

This comment has been minimized.

Contributor

mwwaters commented Oct 1, 2018

I am working on a proposal for adding DNSSEC to Go. DNSSEC validation requires multiple queries up to the DNSKEY RRSet of root.

There are a few solutions I have considered for the proposal. All solutions will have x/net/dns/dnsmessage adding necessary RRs and a new package, x/net/dns/dnssec, to perform validation. Any solution will also have to support EDNS0 in case of DNSSEC queries. The three possible solutions include:

  1. Vendor dnssec and add exported functions to net such as LookupIPAddrSecure, LookupMXSecure, etc.

  2. Add a LookupBytes function returns the byte slice of the DNS response for the caller. The net package still checks query's Header and Question. The call will have to re-parse the byte slice but can skip over the question. From exchange() up the call stack, a []byte return would need to be added.

  3. LookupRRSet function which uses duplicate structures defined in the net package. The dnssec package can take net package's structures and transform them back to dnsmessage package. Using the dnsmessage structures is not an option since the caller's dnsmessage package is different than the vendored package.

#1 is the cleanest if the extra dependency is acceptable. #2 is clean for unix, but ugly for Windows. Windows 7 and up can support DNSSEC lookups, but the bytes of the DNS response would have to be reconstructed. #3 has duplication of code and two copies made of the unpacked response.

I would lean towards #1, but do not know how serious the dependency issue is. If the dependency issue is a deal-breaker, then I can make a proposal for #3. The proposal would target Go 1.13's release cycle.

@ianlancetaylor

This comment has been minimized.

Contributor

ianlancetaylor commented Oct 1, 2018

Vendoring dnssec is OK; we've already got dnsmessage in vendor/golang_org/x/net/dns/dnsmessage.

Why LookupIPAddrSecure? Why not just make LookupIPAddr use DNSSEC if available?

@mwwaters

This comment has been minimized.

Contributor

mwwaters commented Oct 3, 2018

The most immediate reason is systemd-resolved's stub resolver (the 127.0.0.53 /etc/resolv.conf server) always strips out DNSSEC records. On my own computer (Ubuntu 18.04), "dig . DNSKEY" gave an empty result while "dig @8.8.8.8 . DNSKEY" gave the expected result. I had to disable systemd-resolved to get a DNSKEY lookup. Ubnutu Bug Report

To soft-fail the lookup routine, one way is to have always require valid DNSSEC if DNSKEY/RRSIG for root is successful. It is unlikely to have records stripped out for other queries if the root DNSKEY lookup is successful. To hard-fail, what about adding a parameter such as "DNSSECStrict" to Resolver? Hard-fail means either getting validation of either NSEC of a DS record or full validation.

I would also like a LookupTXTSecure function in particular, so the caller could know the TXT record was verified. Verifying TXT records in particular has a use for the MTA-STS proposal and for DMARC/DKIM records. DNS-01 challenges with ACME could also use knowledge of whether TXT records are secure, though CAs would also need a CAA record lookup. LookupTXTSecure could be added later though, in a different issue and CL.

@mikioh

This comment has been minimized.

Contributor

mikioh commented Oct 3, 2018

@mwwaters,

I'm not sure what's the goal of this issue but enabling security-aware DNS stub resolver as defined in RFC 4033 sounds reasonable, I mean, not entering the territory of DNSSEC-based technologies such as DANE, DSO or other fancy features from IETF dnsop-wg.

As you mentioned, a small start is always preferable, for example, 1) add a few RRs to dns/dnsmessage package of x/net, 2) create dns/dnssec package of x/net for implementing a validator for stub resolver, 3) stop, take a breath and re-consider adaptation to the standard library; API surface (e.g., why not extending net.Resolver?), dependency management (especially for cipher suite packages), etc. I feel like having dns/dnslookup package of x/net is not so bad.

@iangudger, thoughts?

@iangudger

This comment has been minimized.

Contributor

iangudger commented Oct 3, 2018

I am all for adding DNSSEC and other features to both x/net/dns and the standard library. The approach listed by @mikioh sounds reasonable to me.

That said, do @mikioh or @bradfitz (or someone else?) have the bandwidth to review changes like this?

@mwwaters

This comment has been minimized.

Contributor

mwwaters commented Oct 3, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment