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.