Get NS record for domain using dig

digdomain-name-systemns-record

I'm currently trying to write a script that validates, whether a given record attached to a name is available via all nameservers that are responsible for that name.

E.g. I would like to check whether there is an A record for foo.example.com available at all NS entries for the example.com domain (a.iana-servers.net and b.iana-servers.net)

The script works by first querying the NS records for the given name (or its parents if that fails; e.g. since foo.example.com. doesn't have an NS entry, we try example.com. next and finally .com.), and then checking the A record with all nameservers.

 name=foo.example.com
 # get the nameservers for ${name}
 sname=${name}
 until [ -z "x${sname}" ]; do
    dns=$(dig +short NS "${sname}")
    if [ "x${dns}" != "x" ]; then
      break
    fi
    sname=${sname#*.}
done
# now that we have a list of nameservers in $dns, we query them
for ns in $dns; do
    dig +short A "${name}" @$"{ns}"
done

This kind of works, unless the name is actually a CNAME.
In this case, a dig NS will return the CNAME record (rather than the NS record or no record)

$ dig +noall +answer NS foo.example.com
foo.example.com. 300 IN CNAME bar.example.com.
$ dig +short NS foo.example.com
bar.example.com.
$ dig A foo.example.com @bar.example.com
;; global options: +cmd
;; connection timed out; no servers could be reached
$

Instead I would like to have something like:

$ dig +short NS foo.example.com
$ dig +short NS example.com
a.iana-servers.net.
b.iana-servers.net.
$ dig +short A foo.example.com @a.iana-servers.net.
93.184.216.34
$

So my question is: how can I force dig to only return the NS records, and not some other record which points to a host that is not a nameserver?

One obvious solution is to parse the output of dig +noall +answer to see whether it actually contains an NS record, but this seems rather clumsy and error prone…

Best Answer

If you're at all comfortable with Perl, you can save yourself a whole lot of pretty finicky work by writing your test as a plugin to Zonemaster. Its framework already has (correct) code to find the right set of name servers and send a query to all of them.