All recursive nameserver software are shipped with the list of current root nameservers and their IP addresses.
This gives a basis as this can change but slowly.
Upon start, the server will connect any of the above IP address to retrieve, through a . NS
DNS query the current list of root nameservers, and then update its internal list and use that for all further needs. This process is called "priming".
If you want details, this is all explained in RFC 8109 "Initializing a DNS Resolver with Priming Queries"
As for your question on glues, remember that glues are a specific edge case. If you have domain adomain.example
using ns1.anotherdomain.test
then there are no glue records anywhere. See the definition of "glue records" in this new document on DNS terminology: https://www.rfc-editor.org/rfc/rfc7719#section-6 :
Glue records: "[Resource records] which are not part of the
authoritative data [of the zone], and are address resource records
for the [name servers in subzones]. These RRs are only necessary
if the name server's name is 'below' the cut, and are only used as
part of a referral response." Without glue "we could be faced
with the situation where the NS RRs tell us that in order to learn
a name server's address, we should contact the server using the
address we wish to learn." (Definition from [RFC1034],
Section 4.2.1)
As for "When I send out a DNS request for my.example.net, it goes to the DNS root zone" no, this is not true. Your system uses one (or multiple) recursive DNS servers, either locally or public. You send all your DNS queries to them. They are in charge, like their name imply, to do iterative queries to multiple nameservers, in a recursive fashion, starting from the root, if their current cache has no data to reply to your query.
So let us describe with an example, using a real name, like www.stackexchange.com
.
You can do dig +trace www.stackexchange.com A
to see exactly what happens, the +trace
triggers full recursive mode and shows what any recursive nameserver does when its cache is empty.
But we can redo it manually.
And if you want the specific algorithm to follow, have a read at "4.3.2. Algorithm" in RFC 1034 DOMAIN NAMES - CONCEPTS AND FACILITIES (but note that there are later additions, specially for DNSSEC and other records like DNAME)
For example see https://gitlab.isc.org/isc-projects/bind9/blob/master/lib/dns/rootns.c
This is part of BIND source code. But it is basically the content of a reply for . NS
with IP addresses, that is current list of root nameservers and their IPv4 and IPv6 addresses.
We ignore the DNS priming step here (updating the above list)
Step 1
Pick one of the above IP addresses and do your query:
$ dig @192.112.36.4 www.stackexchange.com A +nodnssec
; <<>> DiG 9.12.0 <<>> @192.112.36.4 www.stackexchange.com A +nodnssec
; (1 server found)
;; global options: +cmd
;; Sending:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59725
;; flags: rd ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;www.stackexchange.com. IN A
;; QUERY SIZE: 62
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59725
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 27
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;www.stackexchange.com. IN A
;; AUTHORITY SECTION:
com. 2d IN NS k.gtld-servers.net.
com. 2d IN NS e.gtld-servers.net.
com. 2d IN NS g.gtld-servers.net.
com. 2d IN NS c.gtld-servers.net.
com. 2d IN NS l.gtld-servers.net.
com. 2d IN NS j.gtld-servers.net.
com. 2d IN NS h.gtld-servers.net.
com. 2d IN NS a.gtld-servers.net.
com. 2d IN NS b.gtld-servers.net.
com. 2d IN NS m.gtld-servers.net.
com. 2d IN NS d.gtld-servers.net.
com. 2d IN NS f.gtld-servers.net.
com. 2d IN NS i.gtld-servers.net.
;; ADDITIONAL SECTION:
a.gtld-servers.net. 2d IN A 192.5.6.30
b.gtld-servers.net. 2d IN A 192.33.14.30
c.gtld-servers.net. 2d IN A 192.26.92.30
d.gtld-servers.net. 2d IN A 192.31.80.30
e.gtld-servers.net. 2d IN A 192.12.94.30
f.gtld-servers.net. 2d IN A 192.35.51.30
g.gtld-servers.net. 2d IN A 192.42.93.30
h.gtld-servers.net. 2d IN A 192.54.112.30
i.gtld-servers.net. 2d IN A 192.43.172.30
j.gtld-servers.net. 2d IN A 192.48.79.30
k.gtld-servers.net. 2d IN A 192.52.178.30
l.gtld-servers.net. 2d IN A 192.41.162.30
m.gtld-servers.net. 2d IN A 192.55.83.30
a.gtld-servers.net. 2d IN AAAA 2001:503:a83e::2:30
b.gtld-servers.net. 2d IN AAAA 2001:503:231d::2:30
c.gtld-servers.net. 2d IN AAAA 2001:503:83eb::30
d.gtld-servers.net. 2d IN AAAA 2001:500:856e::30
e.gtld-servers.net. 2d IN AAAA 2001:502:1ca1::30
f.gtld-servers.net. 2d IN AAAA 2001:503:d414::30
g.gtld-servers.net. 2d IN AAAA 2001:503:eea3::30
h.gtld-servers.net. 2d IN AAAA 2001:502:8cc::30
i.gtld-servers.net. 2d IN AAAA 2001:503:39c1::30
j.gtld-servers.net. 2d IN AAAA 2001:502:7094::30
k.gtld-servers.net. 2d IN AAAA 2001:503:d2d::30
l.gtld-servers.net. 2d IN AAAA 2001:500:d937::30
m.gtld-servers.net. 2d IN AAAA 2001:501:b1f9::30
;; Query time: 121 msec
;; SERVER: 192.112.36.4#53(192.112.36.4)
;; WHEN: Tue Mar 26 12:22:23 EST 2019
;; MSG SIZE rcvd: 874
So the server at 192.112.36.4
is replying to us:
NOERROR
: our request was valid
- no
aa
entry in the flags, we did not get an authoritative reply to our answer, just pointers on where to go next
- "WARNING: recursion requested but not available": as expected the authoritative nameserver on
.
we query does no do recursion for us
- so this server knows, to help our request, only authoritative nameservers on
.COM
; it provides their names and IP addresses.
Now, the recursive nameserver is not mandated to trust the content of the "ADDITIONAL SECTION". It could go again with m.gtld-servers.net.
for example and ask the same authoritative nameserver about it. In the same way it will give back data that it is not authoritative on this name but knows nameservers of .NET
and giving back their name and IP addresses. Here, since their names are all again in .NET
, they are in-bailiwick, and the server has to trust the IP addresses provided.
Step 2
Picking up any of the above IP addresses, we do our query again:
$ dig @192.26.92.30 www.stackexchange.com A +nodnssec
; <<>> DiG 9.12.0 <<>> @192.26.92.30 www.stackexchange.com A +nodnssec
; (1 server found)
;; global options: +cmd
;; Sending:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45273
;; flags: rd ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;www.stackexchange.com. IN A
;; QUERY SIZE: 62
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45273
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 5
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;www.stackexchange.com. IN A
;; AUTHORITY SECTION:
stackexchange.com. 2d IN NS ns-925.awsdns-51.net.
stackexchange.com. 2d IN NS ns-1029.awsdns-00.org.
stackexchange.com. 2d IN NS ns-cloud-d1.googledomains.com.
stackexchange.com. 2d IN NS ns-cloud-d2.googledomains.com.
;; ADDITIONAL SECTION:
ns-cloud-d1.googledomains.com. 2d IN AAAA 2001:4860:4802:32::6d
ns-cloud-d1.googledomains.com. 2d IN A 216.239.32.109
ns-cloud-d2.googledomains.com. 2d IN AAAA 2001:4860:4802:34::6d
ns-cloud-d2.googledomains.com. 2d IN A 216.239.34.109
;; Query time: 108 msec
;; SERVER: 192.26.92.30#53(192.26.92.30)
;; WHEN: Tue Mar 26 12:35:56 EST 2019
;; MSG SIZE rcvd: 273
Here the server at 192.26.92.30
provides us with roughly the same kind of answer previously: it is not authoritative for the name we seek about, but provides back its nameserver and IP addresses.
Again, the namserver could not go ask for the name ns-cloud-d1.googledomains.com.
but it will obviously come from the same namserver, as same TLD, so it can use above IP addresses. Or it can do the resolution from scratch again for names ns-925.awsdns-51.net.
or ns-1029.awsdns-00.org.
which are external to the .COM
zone, hence no IP addresses provided.
Step 3
So to simplify using one of the above IP addresses and redoing the query:
$ dig @216.239.34.109 www.stackexchange.com A +nodnssec
; <<>> DiG 9.12.0 <<>> @216.239.34.109 www.stackexchange.com A +nodnssec
; (1 server found)
;; global options: +cmd
;; Sending:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16720
;; flags: rd ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;www.stackexchange.com. IN A
;; QUERY SIZE: 62
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16720
;; flags: qr aa rd; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;www.stackexchange.com. IN A
;; ANSWER SECTION:
www.stackexchange.com. 5m IN CNAME stackexchange.com.
stackexchange.com. 5m IN A 151.101.1.69
stackexchange.com. 5m IN A 151.101.65.69
stackexchange.com. 5m IN A 151.101.129.69
stackexchange.com. 5m IN A 151.101.193.69
;; Query time: 149 msec
;; SERVER: 216.239.34.109#53(216.239.34.109)
;; WHEN: Tue Mar 26 12:38:34 EST 2019
;; MSG SIZE rcvd: 128
Note an important difference: the AA flag, meaning that the nameserver we just queried is indeed authoritative on the name we were querying so its results are "final".
In fact it shows that our name is a CNAME
record type, but it does provide the IP addresses of the target, so our query is finished, we were able to resolve that www.stackexchange.com
right now and from where this was done, is IP addresses 151.101.1.69
and 151.101.65.69
and 151.101.129.69
and 151.101.193.69
.