Course outline · 0% complete

0/30 lessons0%

Course overview →

DNS resolution, from stub resolver to authoritative server

lesson 8-1 · ~13 min · 23/30

A distributed database with no center

Humans use names, and packets need addresses. DNS (domain name system) is the lookup service in between, and it is worth understanding as a database design, because its shape explains every one of its behaviors.

A name is read right to left, from the most general label to the most specific. The full form ends in an invisible dot for the root.

www.docs.example.com.
 |    |     |     |  |
 |    |     |     |  root, the empty label
 |    |     |     top level domain, com
 |    |     the domain somebody registered
 |    a subdomain the owner created
 the host or service name

That full form is an FQDN (fully qualified domain name). Each dot separated piece is a label, at most 63 characters, and the whole name is at most 253.

The hierarchy is not decoration, it is delegation. The root operators do not know where example.com lives. They only know which servers are authoritative for com. The com servers do not know about www.docs.example.com, they only know the servers for example.com. Each level knows only the next level down, which is exactly the property that lets one system serve hundreds of millions of names with no central database and no single owner.

The four actors

ActorRole
Stub resolverthe tiny client in your operating system, asks one question
Recursive resolverdoes the legwork and caches, run by your ISP or 1.1.1.1
Root servers13 named server sets that answer "who handles this TLD"
TLD serversanswer "who is authoritative for this domain"
Authoritative servershold the actual records for the domain

Two query styles exist and the difference matters.

- A recursive query says "get me the final answer, I will wait". Your stub resolver sends this to the recursive resolver. - An iterative query says "answer if you can, otherwise tell me who to ask next". The recursive resolver sends these to the root, the TLD, and the authoritative servers in turn.

So there is exactly one recursive query and several iterative ones per full lookup. Walk the whole thing for www.example.com on a cold cache:

1. Your browser asks the stub resolver, which asks the recursive resolver at 192.168.1.1 or 1.1.1.1, port 53. 2. The resolver asks a root server: "A record for www.example.com?" The root replies with a referral: "I do not know, but the com servers are a.gtld-servers.net and others, here are their addresses." 3. The resolver asks a com server the same question, and gets another referral: "the servers for example.com are ns1.example.com and ns2.example.com." 4. The resolver asks ns1.example.com, which is authoritative, and finally gets an answer: "www.example.com is 93.184.216.34, TTL 3600." 5. The resolver caches every step it learned and returns the answer to your stub resolver, which hands it to the browser.

Four queries for one name, on a cold cache. Almost every real lookup skips most of them, because the resolver has the root and TLD referrals cached already, which is the subject of Lesson 8-2.

your hoststubrecursiveresolverroot serverscom serversexample.com ns1 recursivequeryask comask example.comhere is the A recordthe resolver caches every referral, so the next lookup skips most of the chain
One recursive query from your machine turns into a chain of iterative queries, each answered with a referral one level deeper.

Watching the chain yourself

dig +trace performs the iterative walk itself instead of asking a resolver, so you see every referral. Run it on any name you like.

dig +trace www.example.com
.      518400 IN NS a.root-servers.net.
.      518400 IN NS b.root-servers.net.
;; Received 811 bytes from 192.168.1.1#53(192.168.1.1)

com.   172800 IN NS a.gtld-servers.net.
com.   172800 IN NS b.gtld-servers.net.
;; Received 1174 bytes from 198.41.0.4#53(a.root-servers.net)

example.com. 172800 IN NS ns1.example.com.
example.com. 172800 IN NS ns2.example.com.
;; Received 576 bytes from 192.5.6.30#53(a.gtld-servers.net)

www.example.com. 3600 IN A 93.184.216.34
;; Received 60 bytes from 199.43.135.53#53(ns1.example.com)

Read the Received from lines and the whole hierarchy is visible: the root answered with com name servers, a com server answered with example.com name servers, and an example.com server answered with the address. NS records are the delegations, and the number before IN is the TTL in seconds.

For everyday work, the short form is enough:

dig +short www.example.com A
93.184.216.34

Two transport notes. DNS normally uses UDP port 53, because a query and answer fit in one small datagram and a retry is cheaper than a handshake. It falls back to TCP port 53 when the answer is too large, which is common for DNSSEC signed zones and long record sets. Encrypted variants exist and are now widespread, DoT on TCP port 853 and DoH over HTTPS on 443, and both hide your lookups from the network while making them invisible to your own troubleshooting tools.

The failures and what they mean

DNS returns a status code, and each one points somewhere specific.

StatusNameMeans
NOERRORsuccessan answer, or an empty answer for that record type
NXDOMAINno such nameauthoritatively, this name does not exist
SERVFAILserver failurethe resolver could not complete, or DNSSEC failed
REFUSEDrefusedthe server will not answer you, often a policy filter
Timeoutno replyport 53 blocked, wrong resolver address, server down

Three distinctions that resolve most confusion:

- NXDOMAIN is not NOERROR with no records. NXDOMAIN says the name is absent. NOERROR with an empty answer says the name exists but has no record of that type, for example an A query for a name that only has MX records. Different problems, different fixes. - SERVFAIL is usually not your fault. It commonly means the authoritative servers are unreachable or the zone's DNSSEC signatures do not validate. - A lame delegation is when the parent points at a server that is not actually authoritative for the zone. Lookups then work intermittently, depending on which name server the resolver happened to try, and intermittent DNS is nearly always either this or one of several name servers being out of sync.

A practical habit. When a name behaves strangely, query the authoritative server directly and compare with what a public resolver returns.

dig @ns1.example.com www.example.com +norecurse
dig @1.1.1.1 www.example.com

If the authoritative answer is right and the public one is wrong, you are looking at a cache, which is the next lesson.