Recursive DNS servers send the whole original query to authoritative servers

July 12, 2017

As a long term sysadmin, I usually feel that I have a solid technical grasp of DNS (apart from DNSSEC, which I ignore on principle). Then every so often, I get to find out that I'm wrong. Today is one of those days.

Before today, if you had asked me how a recursive DNS server did a lookup from authoritative servers, I would have told you what is basically the standard story. If you're looking up the A record for, your local recursive server first asks a random root server for the NS records for .com, then asks one of the .com DNS servers for the NS records for, then asks one of those theoretically authoritative DNS servers, and so on. Although this describes the chain of NS delegations that your recursive DNS server typically gets back, it turns out that this doesn't accurately describe what your server usually sends as its queries. The normal practice today is that your recursive DNS server sends the full original query to each authoritative server. It doesn't ask the root servers 'what is the NS for .com'; instead it asks the root servers 'what is the A record for', and they send back an answer that is basically 'I have no idea, ask one of these .com nameservers'.

Once I thought about it, this behavior made a lot of sense because DNS clients don't know in advance where zone delegation boundaries are. It's common for there to be zone boundaries between each ., but it's not always the case; you can certainly have zones where the zone boundaries are further apart. You can even have zones where it varies by the name. Consider a hypothetical .ca zone operator who allows registration of both <domain>.<province>.ca (eg and <domain>.ca (eg, and does not have separate <province>.ca zones; they just carry all of the data in one zone without internal NS records. Here has a NS but doesn't, and your client certainly can't know which is which in advance. When the client has no idea where the zone boundaries are, the simple thing to do is to send the whole original query off to each step of the delegation chain and see what they say. This way you don't have to try any sort of backtracking when you ask for a NS for and get a no data answer back.

Now, you might ask if sending the full query to all DNS servers in the chain like this has privacy implications. Why yes, it does, and there are proposed ways to work around it, such as RFC 7816 query minimization. Some DNS servers are already taking steps here; for example, current versions of Unbound have the qname-minimisation option in unbound.conf.

(My discovery is due to reading this article. I believe that the article overstates things a bit itself, but that's another entry (or see this Twitter thread).)

Written on 12 July 2017.
« The BSD r* commands and the history of privileged TCP ports
Understanding the .io TLD's DNS configuration vulnerability »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Wed Jul 12 01:15:35 2017
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.