Converting from nslookup to dig

I have used nslookup for years to access information in the Domain Name Systems (DNS), and was sad to see that it was moved to the “deprecated” state when dig (domain information groper) was released. Since I knew nslookup(1m) inside and out, I put off learning about dig, and instead focused on learning other interesting technologies. I recently wanted to add TSIG support to a DNS server, and needed to be able to test signing keys. I didn’t see support in nslookup, so I decided to sit down and learn everything there was to know about dig.

To get started with dig, you can execute dig with the “-h” (help) option:

$ dig -h

Usage:  dig [@global-server] [domain] [q-type] [q-class] {q-opt}
        {global-d-opt} host [@local-server] {local-d-opt}
        [ host [@local-server] {local-d-opt} [...]]
Where:  domain    are in the Domain Name System
        q-class  is one of (in,hs,ch,...) [default: in]
        q-type   is one of (a,any,mx,ns,soa,hinfo,axfr,txt,...) [default:a]
                 (Use ixfr=version for type ixfr)
        q-opt    is one of:
                 -x dot-notation     (shortcut for in-addr lookups)
                 -n                  (nibble form for reverse IPv6 lookups)
                 -f filename         (batch mode)
                 -b address          (bind to source address)
                 -p port             (specify port number)
                 -t type             (specify query type)
                 -c class            (specify query class)
                 -k keyfile          (specify tsig key file)
                 -y name:key         (specify named base64 tsig key)
        d-opt    is of the form +keyword[=value], where keyword is:
                 +[no]vc             (TCP mode)
                 +[no]tcp            (TCP mode, alternate syntax)
                 +time=###           (Set query timeout) [5]
                 +tries=###          (Set number of UDP attempts) [3]
                 +domain=###         (Set default domainname)
                 +bufsize=###        (Set EDNS0 Max UDP packet size)
                 +ndots=###          (Set NDOTS value)
                 +[no]search         (Set whether to use searchlist)
                 +[no]defname        (Ditto)
                 +[no]recursive      (Recursive mode)
                 +[no]ignore         (Don't revert to TCP for TC responses.)
                 +[no]fail           (Don't try next server on SERVFAIL)
                 +[no]besteffort     (Try to parse even illegal messages)
                 +[no]aaonly         (Set AA flag in query)
                 +[no]adflag         (Set AD flag in query)
                 +[no]cdflag         (Set CD flag in query)
                 +[no]cmd            (Control display of command line)
                 +[no]comments       (Control display of comment lines)
                 +[no]question       (Control display of question)
                 +[no]answer         (Control display of answer)
                 +[no]authority      (Control display of authority)
                 +[no]additional     (Control display of additional)
                 +[no]stats          (Control display of statistics)
                 +[no]short          (Disable everything except short
                                      form of answer)
                 +[no]all            (Set or clear all display flags)
                 +[no]qr             (Print question before sending)
                 +[no]nssearch       (Search all authoritative nameservers)
                 +[no]identify       (ID responders in short answers)
                 +[no]trace          (Trace delegation down from root)
                 +[no]dnssec         (Request DNSSEC records)
                 +[no]multiline      (Print records in an expanded format)
        global d-opts and servers (before host name) affect all queries.
        local d-opts and servers (after host name) affect only that lookup.

This will print all of the availble options along with a short description of the option. When used to lookup information in DNS, dig takes the following form:

dig [@name server to use] [domain] [record-type]

“@server” represents the DNS server to query, “domain” represents the domain entry to query (e.g., www.daemons.net), and “record-type” indicates the type of record to retrieve. To lookup the A record for the host www.daemons.net, dig can be executed with the domain entry to resolve:

$ dig www.daemons.net

; <<>> DiG 9.2.2 <<>> www.daemons.net
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19436
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2

;; QUESTION SECTION:
;www.daemons.net.               IN      A

;; ANSWER SECTION:
www.daemons.net.        16140   IN      A       66.148.84.65

;; AUTHORITY SECTION:
daemons.net.            28078   IN      NS      olympus.daemons.net.
daemons.net.            28078   IN      NS      elysium.daemons.net.

;; ADDITIONAL SECTION:
elysium.daemons.net.    121832  IN      A       206.222.17.178
olympus.daemons.net.    35432   IN      A       66.148.71.8

;; Query time: 22 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Thu Oct 20 16:12:51 2005
;; MSG SIZE  rcvd: 125

This will cause dig to retrive the A record (the default record type) from one of the servers defined in the local name server repository (e.g., /etc/resolv.conf). If you would like to specify the DNS server to query, the server name can be appended to the “@” symbol and passed as an argument to dig:

$ dig @192.168.1.1 www.daemons.net A

; <<>> DiG 9.2.2 <<>> @192.168.1.1 www.daemons.net A
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35663
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2

;; QUESTION SECTION:
;www.daemons.net.               IN      A

;; ANSWER SECTION:
www.daemons.net.        15949   IN      A       66.148.84.65

;; AUTHORITY SECTION:
daemons.net.            27887   IN      NS      olympus.daemons.net.
daemons.net.            27887   IN      NS      elysium.daemons.net.

;; ADDITIONAL SECTION:
elysium.daemons.net.    121641  IN      A       206.222.17.178
olympus.daemons.net.    35241   IN      A       66.148.71.8

;; Query time: 11 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Thu Oct 20 16:16:03 2005
;; MSG SIZE  rcvd: 125

As with nslookup, dig can be used to retrieve all of the standard record types (e.g., A, MX, SOA, NS, etc.). The following example show how to retrieve the MX (mail exchangers) records for the domain daemons.net:

$ dig @192.168.1.1 daemons.net MX

; <<>> DiG 9.2.2 <<>> @192.168.1.1 daemons.net MX
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 4

;; QUESTION SECTION:
;daemons.net.                   IN      MX

;; ANSWER SECTION:
daemons.net.            84867   IN      MX      20 deimos.daemons.net.
daemons.net.            84867   IN      MX      10 phobos.daemons.net.

;; AUTHORITY SECTION:
daemons.net.            27791   IN      NS      elysium.daemons.net.
daemons.net.            27791   IN      NS      olympus.daemons.net.

;; ADDITIONAL SECTION:
phobos.daemons.net.     2029    IN      A       206.222.17.179
deimos.daemons.net.     84867   IN      A       66.148.71.29
elysium.daemons.net.    121545  IN      A       206.222.17.178
olympus.daemons.net.    35145   IN      A       66.148.71.8

;; Query time: 23 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Thu Oct 20 16:17:38 2005
;; MSG SIZE  rcvd: 183

dig also supports numerous options to control which pieces of the query and response are displayed. To view just the result of a query (e.g., just an IP or FQDN), dig’s “+short” option can be used to disable all extraneous output (perfect for shell scripts):

$ dig +short @192.168.1.1 www.daemons.net a
66.148.84.65

If you need to resolve IP addresses to hostname, you are in luck! dig provides the “-x” option to retrieve the PTR record for in-addr.arpa entries, and performs all the translations for you:

$ dig @192.168.1.1 -x 206.222.17.178

; <<>> DiG 9.2.2 <<>> @192.168.1.1 -x 206.222.17.178
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36325
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 2

;; QUESTION SECTION:
;178.17.222.206.in-addr.arpa.   IN      PTR

;; ANSWER SECTION:
178.17.222.206.in-addr.arpa. 86389 IN   PTR     elysium.daemons.net.

;; AUTHORITY SECTION:
17.222.206.in-addr.arpa. 86389  IN      NS      dns3.ee.net.
17.222.206.in-addr.arpa. 86389  IN      NS      dns1.ee.net.
17.222.206.in-addr.arpa. 86389  IN      NS      dns2.ee.net.

;; ADDITIONAL SECTION:
dns2.ee.net.            172789  IN      A       206.222.1.2
dns3.ee.net.            172789  IN      A       206.222.1.3

;; Query time: 20 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Thu Oct 20 20:18:46 2005
;; MSG SIZE  rcvd: 170

Dig can also perform zone file transfers with the AXFR protocol:

$ dig @66.148.71.8 daemons.net AXFR
;; Connection to 66.148.71.8#53(66.148.71.8) for daemons.net failed: connection refused.

The daemons.net DNS adminstrator is limiting zone transfers to pre-defined IP address, so unfortunately the transfer did not complete succesfully. If zone transfers were supported, the AXFR would retrieve the zone file for the domain daemons.net. If you are having problems with DNS reslution, dig provides numerous options to help troubleshoot problems. The “trace” option can be super useful for tracing a query through the entire hierarchical DNS system:

$ dig +trace @192.168.1.1 www.daemons.net a

; <<>> DiG 9.2.2 <<>> +trace @192.168.1.1 www.daemons.net a
;; global options:  printcmd
.                       518210  IN      NS      L.ROOT-SERVERS.NET.
.                       518210  IN      NS      M.ROOT-SERVERS.NET.
.                       518210  IN      NS      A.ROOT-SERVERS.NET.
.                       518210  IN      NS      B.ROOT-SERVERS.NET.
.                       518210  IN      NS      C.ROOT-SERVERS.NET.
.                       518210  IN      NS      D.ROOT-SERVERS.NET.
.                       518210  IN      NS      E.ROOT-SERVERS.NET.
.                       518210  IN      NS      F.ROOT-SERVERS.NET.
.                       518210  IN      NS      G.ROOT-SERVERS.NET.
.                       518210  IN      NS      H.ROOT-SERVERS.NET.
.                       518210  IN      NS      I.ROOT-SERVERS.NET.
.                       518210  IN      NS      J.ROOT-SERVERS.NET.
.                       518210  IN      NS      K.ROOT-SERVERS.NET.
;; Received 340 bytes from 192.168.1.1#53(192.168.1.1) in 22 ms

net.                    172800  IN      NS      A.GTLD-SERVERS.net.
net.                    172800  IN      NS      G.GTLD-SERVERS.net.
net.                    172800  IN      NS      H.GTLD-SERVERS.net.
net.                    172800  IN      NS      C.GTLD-SERVERS.net.
net.                    172800  IN      NS      I.GTLD-SERVERS.net.
net.                    172800  IN      NS      B.GTLD-SERVERS.net.
net.                    172800  IN      NS      D.GTLD-SERVERS.net.
net.                    172800  IN      NS      L.GTLD-SERVERS.net.
net.                    172800  IN      NS      F.GTLD-SERVERS.net.
net.                    172800  IN      NS      J.GTLD-SERVERS.net.
net.                    172800  IN      NS      K.GTLD-SERVERS.net.
net.                    172800  IN      NS      E.GTLD-SERVERS.net.
net.                    172800  IN      NS      M.GTLD-SERVERS.net.
;; Received 502 bytes from 198.32.64.12#53(L.ROOT-SERVERS.NET) in 81 ms

daemons.net.            172800  IN      NS      elysium.daemons.net.
daemons.net.            172800  IN      NS      olympus.daemons.net.
;; Received 109 bytes from 192.5.6.30#53(A.GTLD-SERVERS.net) in 39 ms

www.daemons.net.        86400   IN      A       66.148.84.65
daemons.net.            86400   IN      NS      olympus.daemons.net.
daemons.net.            86400   IN      NS      elysium.daemons.net.
;; Received 125 bytes from 206.222.17.178#53(elysium.daemons.net) in 46 ms

The output shows that the first query requested the TLD server responsible (L.ROOT-SERVERS.NET in this case) for the .net domain, the second query requested the name servers registered to daemons.net, and the final query requested the A record for the host www.daemons.net. Dig is a super cool and powerful utility!! I how to cover TSIG and signed DNS queries in a future BLOG post.

Leave a Reply

Your email address will not be published. Required fields are marked *