Why don't NS records contain IP addresses?
The point of an NS record is to tell client which name server will know for sure the actual IP address for a domain name. So for instance, the following query tells you that if you want to get an authoritative answer about facebook.com
you must ask a.ns.facebook.com
:
> dig ns facebook.com 19:58:27
; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> ns facebook.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32063
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;facebook.com. IN NS
;; ANSWER SECTION:
facebook.com. 65000 IN NS a.ns.facebook.com.
facebook.com. 65000 IN NS b.ns.facebook.com.
;; Query time: 13 msec
;; SERVER: 127.0.1.1#53(127.0.1.1)
;; WHEN: Sun Mar 20 19:58:40 CET 2016
;; MSG SIZE rcvd: 65
This seems cool and useful but I'm wondering why the ANSWER
section contains the hostname and not IP of the authoritative source? Wouldn't it be easier for the client to get the actual IP address of the authoritative source and not the hostname?
I mean if it gets the hostname it will have to make another query to resolve this hostname into an IP and then ask this new IP about the initial facebook.com
domain it was looking for. Isn't this inefficient?
I'd be interested in answer that points me to some paragraphs in some RFC that explains this problem.
The solution to the problem is DNS glue records, which are described at What is a glue record?.
RFC 1035 Section 3.3.11 states
"... Note that the class may not indicate the protocol family which should be used to communicate" with the host, although it is typically a strong hint."
Returning an IP address would be tantamount to stating the method by which the host can be contacted, which goes against the RFC.
Jason provided the DNS mechanism that works around the issue you described, but we still haven't taken a look at why things are done this way.
Let's say that I own example.com
, and I've contracted some of my website content out to a content delivery company named Contoso. Their platform requires us to delegate sub.example.com
to their nameservers so that they can control what responses are returned.
; SOA and MX omitted from this example
$ORIGIN example.com.
@ IN NS ns1
@ IN NS ns2
; delegate sub.example.com to Contoso's nameservers
sub IN NS ns1.cdn.contoso.com.
sub IN NS ns2.cdn.contoso.com.
; this is ours, not Contoso's
www IN A 198.51.100.1
As you've noted, we haven't specified the IP addresses of Contoso's nameservers. All our server knows is to tell the internet "we don't manage sub.example.com
, ask Contoso instead". This is very important, because:
- We don't own Contoso.com.
- We can't expect Contoso to coordinate a change of their nameserver IPs with all of their customers. That is exactly what would have to happen if our server was providing those IPs.
So far so good. A year passes, and unbeknownst to us Contoso is changing the IP addresses of their CDN nameservers. Because DNS works the way that it does, all they have to do is update the A
records they return for ns1.cdn
and ns2.cdn.contoso.com.
.
This brings us to an important point: the glue records described by Jason exists to deal with "chicken and egg" scenarios in DNS, such as google.com
telling the world that their nameservers are ns1.google.com
and ns2.google.com
. You should never create glue records pointing to infrastructure that you do not own unless they exist to solve a problem like this:
@ IN NS ns1
@ IN NS ns2
; delegate sub.example.com to ns1 and ns2.sub.example.com
sub IN NS ns1.sub
sub IN NS ns2.sub
; provide the IP addresses of ns1 and ns2 so that nameservers
; on the internet can find them.
;
; these IP addresses are owned by Contoso, not us, and they must
; coordinate changes to these IPs with us
ns1.sub IN A 203.0.113.10
ns1.sub IN A 203.1.113.10
This avoids the chicken and egg scenario, but also makes it so that Contoso has to coordinate every IP change of those nameservers with us. This is very risk prone and undesirable.