dig lookup not returning namservers

After adding some nameservers to my domain for subdelegation i see that if I run a trace and/or query the name servers directly I get the correct name servers back, however if I query the nameserver records just via a dig I do not get a response,

Shouldnt the recursive look up at the DNS stop at the point it retrieves the NS records (nsX.macmonster.co.uk) from dns2.stabletransit.com and pass this back to the client ?

The newly added nameserver records are :

subdomain.codecrab.org. 300     IN      NS      ns1.macmonster.co.uk.
subdomain.codecrab.org. 300     IN      NS      ns2.macmonster.co.uk.

TRACE

    ; <<>> DiG 9.3.6-P1-RedHat-9.3.6-20.P1.el5_8.6 <<>> +trace subdomain.codecrab.org ns
;; global options:  printcmd
.                       94441   IN      NS      f.root-servers.net.
.                       94441   IN      NS      g.root-servers.net.
.                       94441   IN      NS      h.root-servers.net.
.                       94441   IN      NS      i.root-servers.net.
.                       94441   IN      NS      j.root-servers.net.
.                       94441   IN      NS      k.root-servers.net.
.                       94441   IN      NS      l.root-servers.net.
.                       94441   IN      NS      m.root-servers.net.
.                       94441   IN      NS      a.root-servers.net.
.                       94441   IN      NS      b.root-servers.net.
.                       94441   IN      NS      c.root-servers.net.
.                       94441   IN      NS      d.root-servers.net.
.                       94441   IN      NS      e.root-servers.net.
;; Received 228 bytes from 83.138.151.80#53(83.138.151.80) in 0 ms

org.                    172800  IN      NS      a0.org.afilias-nst.info.
org.                    172800  IN      NS      b2.org.afilias-nst.org.
org.                    172800  IN      NS      c0.org.afilias-nst.info.
org.                    172800  IN      NS      a2.org.afilias-nst.info.
org.                    172800  IN      NS      d0.org.afilias-nst.org.
org.                    172800  IN      NS      b0.org.afilias-nst.org.
;; Received 442 bytes from 192.5.5.241#53(f.root-servers.net) in 96 ms

codecrab.org.           86400   IN      NS      dns2.stabletransit.com.
codecrab.org.           86400   IN      NS      dns1.stabletransit.com.
;; Received 95 bytes from 199.19.56.1#53(a0.org.afilias-nst.info) in 108 ms

subdomain.codecrab.org. 300     IN      NS      ns1.macmonster.co.uk.
subdomain.codecrab.org. 300     IN      NS      ns2.macmonster.co.uk.
;; Received 92 bytes from 65.61.188.4#53(dns2.stabletransit.com) in 0 ms

;; connection timed out; no servers could be reached

STANDARD QUERY

; <<>> DiG 9.3.6-P1-RedHat-9.3.6-20.P1.el5_8.6 <<>> subdomain.codecrab.org NS
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 50516
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;subdomain.codecrab.org.                IN      NS

;; Query time: 1 msec
;; SERVER: 83.138.151.80#53(83.138.151.80)
;; WHEN: Thu Sep 26 16:32:34 2013
;; MSG SIZE  rcvd: 40

Additional

[root@monty webtools]# dig ns1.macmonster.co.uk +short
1.1.1.1

Any ideas ?


A recursive DNS resolver requires that the information it recursively acquires is authoritative to return it as a response to a query; it does not make inferences.

Authority is established in DNS using SOA and NS records. The former is used to establish authority among authoritative servers, and is served from within the zone. For instance, the SOA record indicates which copy of the zone data is newer when authoritative DNS servers for some zone are doing a zone transfer. The latter is used to establish authority when querying.

When an NS record for a subdomain is in a domain, and the server that has it is not an authoritative server for the name being queried, this NS record is a delegation record. So, the recursive resolver will query for delegation records starting with the root .. In your case, it goes up the chain toward this response from dns2.stabletransit.com.:

subdomain.codecrab.org. 300     IN      NS      ns1.macmonster.co.uk.

This is a delegation record, because this data does not exist:

subdomain.codecrab.org. 300     IN      NS      dns2.stabletransit.com

What actually existed was this:

codecrab.org.           86400   IN      NS      dns2.stabletransit.com.

So, the server at dns2.stabletransit.com. can give authoritative replies for codecrab.org., because the prior resolver delegated that zone to it. But it is not authoritative for subdomain.codecrab.org., so it cannot answer the query; it can only delegate.

DNS resolvers can of course be configured to be authoritative for any name the administrator wants. However, if they are configured to be authoritative for zones they are trying to delegate, they will instead give replies (without having the data), so this obviously is not done.

The way recursion works is simple, if not initially intuitive. The recursive resolver sends the full query to the nameservers for . (which it has in its hint file for the root zone). The . nameserver sends a reply, but a reply has two components we care about for this purpose: the authority section, and the answer section (there are also the additional section and the question section). The reply will contain records like:

org.                    172800  IN      NS      b0.org.afilias-nst.org.

This tells the recursive resolver to repeat its query over there, because the zone is delegated. It also includes "glue" in the additional section giving the IP addresses of the nameservers in the authority section, beacuse it knows you won't be able to find the nameserver to query it otherwise. This is an administrative decision in managing DNS; if glue records are not present the recursive resolver will query the AAAA or A records for one of the authoritative servers before proceeding.

So, you may notice that when you send your query IN NS subdomain.codecrab.org. to the last delegation, dns2.stabletransit.com., the reply looks like this:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35461
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;subdomain.codecrab.org.                IN      NS

;; AUTHORITY SECTION:
subdomain.codecrab.org. 300     IN      NS      ns2.macmonster.co.uk.
subdomain.codecrab.org. 300     IN      NS      ns1.macmonster.co.uk.

;; Query time: 104 msec
;; SERVER: 65.61.188.4#53(65.61.188.4)
;; WHEN: Sat Sep 28 14:50:45 MDT 2013

Notice how you get neither an additional section nor an answer section (but also NOERROR for the return status). This is because the record is a delegation to ns2.macmonster.co.uk. for subdomain.codecrab.org., for which dns2.stabletransit.com. knows it is not authoritative. There is no additional section because the namesevers are over in co.uk. and administratively it wasn't necessary to include glue because they are resolvable over there (though certainly, glue could have been included). So, to answer your query, because the answer has to come from an answer section (meaning it is identified by the replying server as an answer, coming from authority), your recursive resolver will try to find ns1.macmonster.co.uk., and finding it at 1.1.1.1, will send its query over there.

Of course (as this address is in a debogon prefix) there is no nameserver there (yet). As for ns2.macmonster.co.uk. at 2.2.2.2, if someone at Wanadoo France were to decide that there were to be a nameserver carrying authoritative records for subdomain.codecrab.org. and in particular:

subdomain.codecrab.org 99999999 IN NS now.go.away.or.i.will.taunt.you.a.second.time.

half the time (as often as that nameserver is chosen), the query will return now.go.away.or.i.will.taunt.you.a.second.time. as the nameserver for your zone even though common sense would suggest that it should be ns2.macmonster.co.uk. (and even though it was that latter nameserver which authoritatively gave that answer).


@Zoredache answered the question in a comment. The dig trace shows the answer, the nameservers at the domain level do not resolve:

subdomain.codecrab.org. 300     IN      NS      ns1.macmonster.co.uk.
subdomain.codecrab.org. 300     IN      NS      ns2.macmonster.co.uk.
;; Received 92 bytes from 65.61.188.4#53(dns2.stabletransit.com) in 0 ms

dig: couldn't get address for 'ns1.macmonster.co.uk': not found

... so, both dig queries failed, but the +trace output showed you where it failed. When you run dig +trace, you are following the path that a DNS server would follow to resolve the query, starting at the "root" name servers. Your second query asked your DNS server (83.138.151.80), which did the same thing (effectively), but when it couldn't resolve the ns1/ns2.macmonster.co.uk, so it failed and didn't give an answer. In order to get an answer, those name servers will need to resolve to IP addresses that are running DNS for that subdomain, and the results of the NS query to those servers is the answer that will be returned.

~tommy


Problem: Your delegation records are correct but the used name servers (ns1.macmonster.co.uk and ns2.macmonster.co.uk) do not have correct IP addresses. In my case ns1.macmonster.co.uk has IP 1.1.1.1 and n2.macmonster.co.uk has IP 2.2.2.2. These IP addresses are real and valid but I do not believe that these IP addresses are pointing to DNS servers.

How to fix: I assume that you have used these name servers for some reason. Clarify with macmonster.co.uk why these name servers cannot be connected from the Internet (maybe they are only for local or Intranet purposes) or use different name servers for your delegation.

Why does this not work: Hmm, if my memory serves me right there was a story of Asterix and Obelix trying to get a pass/badge A38 and they must run from room to room to get it. However DNS is more user-friendly than this. If you ask for host1.subdomain.codecrab.org. your DNS tries to resolve this to an IP address. It asks org. for codecrab.org., codecrab.org. for subdomain.codecrab.org. and subdomain.codecrab.org. for host1.subdomain.codecrab.org. If this chain doesn't work - DNS resolving fails.