How does dig +trace actually work?

Solution 1:

dig +trace works by pretending it's a name server and works down the namespace tree using iterative queries starting at the root of the tree, following referrals along the way.

The first thing it does is ask the normal system DNS server for NS records for "."

After it gets a response, which will be the current list of root name servers, it'll pick one and then ask for the A record for that name if it didn't get it in the additional records section the first time so it's got an IP address to send the next query to. Let's say it picks f.root-servers.net whose IP address is 192.5.5.241.

At this point, let's use dig +trace www.google.co.uk. as our command with a domain name we want to trace the resolution path for.

The next behind-the-scenes query will be this:

$ dig +norecurse @192.5.5.241 www.google.co.uk

   ; <<>> DiG 9.9.4 <<>> +norecurse @192.5.5.241 www.google.co.uk
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8962
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 11, ADDITIONAL: 15

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.google.co.uk.              IN      A

;; AUTHORITY SECTION:
uk.                     172800  IN      NS      ns5.nic.uk.
uk.                     172800  IN      NS      ns6.nic.uk.
uk.                     172800  IN      NS      ns4.nic.uk.
uk.                     172800  IN      NS      nsc.nic.uk.
uk.                     172800  IN      NS      ns2.nic.uk.
uk.                     172800  IN      NS      ns3.nic.uk.
uk.                     172800  IN      NS      nsd.nic.uk.
uk.                     172800  IN      NS      nsa.nic.uk.
uk.                     172800  IN      NS      ns7.nic.uk.
uk.                     172800  IN      NS      nsb.nic.uk.
uk.                     172800  IN      NS      ns1.nic.uk.

;; ADDITIONAL SECTION:
ns1.nic.uk.             172800  IN      A       195.66.240.130
ns2.nic.uk.             172800  IN      A       217.79.164.131
ns3.nic.uk.             172800  IN      A       213.219.13.131
ns4.nic.uk.             172800  IN      A       194.83.244.131
ns5.nic.uk.             172800  IN      A       213.246.167.131
ns6.nic.uk.             172800  IN      A       213.248.254.130
ns7.nic.uk.             172800  IN      A       212.121.40.130
nsa.nic.uk.             172800  IN      A       156.154.100.3
nsb.nic.uk.             172800  IN      A       156.154.101.3
nsc.nic.uk.             172800  IN      A       156.154.102.3
nsd.nic.uk.             172800  IN      A       156.154.103.3
ns1.nic.uk.             172800  IN      AAAA    2a01:40:1001:35::2
ns4.nic.uk.             172800  IN      AAAA    2001:630:181:35::83
nsa.nic.uk.             172800  IN      AAAA    2001:502:ad09::3

;; Query time: 45 msec
;; SERVER: 192.5.5.241#53(192.5.5.241)
;; WHEN: Tue Feb 11 19:19:14 MST 2014
;; MSG SIZE  rcvd: 507

Wow, so now we know that there are nameservers for uk and that's the only thing the root server knows about. This is a referral, because we did not ask for recursion (+norecurse turns it off).

Great, we rinse and repeat. This time we pick one of the uk nameservers and ask it the same question.

$ dig +norecurse @195.66.240.130 www.google.co.uk

; <<>> DiG 9.9.4 <<>> +norecurse @195.66.240.130 www.google.co.uk
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 618
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.google.co.uk.              IN      A

;; AUTHORITY SECTION:
google.co.uk.           172800  IN      NS      ns1.google.com.
google.co.uk.           172800  IN      NS      ns3.google.com.
google.co.uk.           172800  IN      NS      ns2.google.com.
google.co.uk.           172800  IN      NS      ns4.google.com.

;; Query time: 354 msec
;; SERVER: 195.66.240.130#53(195.66.240.130)
;; WHEN: Tue Feb 11 19:22:47 MST 2014
;; MSG SIZE  rcvd: 127

Awesome, now we have found out that the uk top-level nameserver knows there's a zone called google.co.uk and tells us to go ask those nameservers our question. This is another referral.

Rinse, repeat.

This time, however, we didn't get A records in the additional records section of the response, so we pick one, say ns2.google.com, and we have to go find it's address. We restart a query (at the root again) and chase down the tree to find the IP address for ns2.google.com. I'll skip that part for brevity, but we learn that the IP for it is 216.239.34.10.

So our next query is:

$ dig +norecurse @216.239.34.10 www.google.co.uk

; <<>> DiG 9.9.4 <<>> +norecurse @216.239.34.10 www.google.co.uk
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33404
;; flags: qr aa; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;www.google.co.uk.              IN      A

;; ANSWER SECTION:
www.google.co.uk.       300     IN      A       74.125.225.216
www.google.co.uk.       300     IN      A       74.125.225.223
www.google.co.uk.       300     IN      A       74.125.225.215

;; Query time: 207 msec
;; SERVER: 216.239.34.10#53(216.239.34.10)
;; WHEN: Tue Feb 11 19:26:43 MST 2014
;; MSG SIZE  rcvd: 82

And we're done! (finally) How do we know we're done? We got an answer to our query, which was the A records for www.google.co.uk. You can also tell because it's not a referral anymore, the aa bit is set in the last response meaning this is the authoritative answer for your query.

So that's what's happening each step along the way when you use dig +trace.

Note that if you have a DNSSEC-aware version of dig and you add +dnssec to the command, you may see a bunch more records. What those extra records are is left as an exercise for the reader... but gets into how dig +sigchase works.

Solution 2:

Lets say you were looking up

www.domain.co.uk

DNS is a heirarchy, starting with root servers that know which servers are authoritative for the TLDs (the last part of the domain name). So the equivilent to

dig subdomain.domain.co.uk

Step by step would be:

dig SOA @g.root-servers.net uk

(ie, query one of the root servers to find who is authoritative for .uk)

This responds with a series of authoritative uk servers, so we ask them who has co.uk

dig SOA @ns6.nic.uk co.uk

And we are told the SOA (authority) is at the same servers

So lets query ns1.nic.uk to see who has domain.co.uk

dig SOA @ns1.nic.uk domain.co.uk

This comes back and says authority for domain is at dns.dns1.de (plus backups);

So now we can ask for the A record:

dig  A @dns.dns2.de www.domain.co.uk

;; QUESTION SECTION:
;www.domain.co.uk.              IN      A

;; ANSWER SECTION:
www.domain.co.uk.       86400   IN      CNAME   domain.co.uk.
domain.co.uk.           86400   IN      A       95.130.17.36