BIND nslookup not resolving Azure, dig is fine

binddomain-name-system

Set up a pair of DNS sinkholes for my organization following the SANS document (http://handlers.sans.org/gbruneau/docs/DNS_Sinkhole_setup.pdf). Both are behaving the same when it comes to the following

My nslookup and dig results for azure.microsoft.com are different, nslookup not resolving.

nslookup:

root@SINK01:~# nslookup azure.microsoft.com
Server:         127.0.0.1
Address:        127.0.0.1#53

** server can't find azure.microsoft.com: NXDOMAIN

dig:

root@SINK01:~# dig azure.microsoft.com

; <<>> DiG 9.9.8-P4 <<>> azure.microsoft.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 1389
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;azure.microsoft.com.           IN      A

;; ANSWER SECTION:
azure.microsoft.com.    34      IN      CNAME   azure.microsoft.com.nsatc.net.
azure.microsoft.com.nsatc.net. 220 IN   CNAME   acom-prod-uswest-01.azurewebsites.net.
acom-prod-uswest-01.azurewebsites.net. 1663 IN CNAME waws-prod-bay-013.vip.azurewebsites.windows.net.

;; AUTHORITY SECTION:
windows.net.            600     IN      SOA     localhost. root.localhost. 2 10800 900 604800 86400

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Aug 24 09:56:10 PDT 2016
;; MSG SIZE  rcvd: 247

/etc/named.conf

   options {
       directory "/var/named";
       version "my own";
       allow-transfer {"none";};
       allow-recursion {192.168.0.0/16; 10.0.0.0/8; localhost;};
       forwarders { 8.8.8.8; 8.8.4.4; };
       query-source address * port 53;
       listen-on { 127.0.0.1; };
};

    zone "." IN {
        type hint;
        file "caching-example/named.root";
};

include "/etc/rndc.key";
include "/var/named/site_specific_sinkhole.conf";
include "/var/named/entire_domain_sinkhole.conf";
include "/var/named/custom_wildcard_sinkhole.conf";
include "/var/named/custom_single_sinkhole.conf";

zone "localhost" IN {
        type master;
        file "caching-example/localhost.zone";
        allow-update { none; };
};

zone "0.0.127.in-addr.arpa" IN {
        type master;
        file "caching-example/named.local";
        allow-update { none; };
};

controls {
       inet 127.0.0.1 port 953
               allow { 127.0.0.1; } keys { "rndc-key"; };
 };

resolv.conf

root@SINK01:~# cat /etc/resolv.conf
nameserver 127.0.0.1
nameserver 192.168.168.87

debug nslookup:

root@SINK01:~# nslookup azure.microsoft.ocm -d2
setup_system()
ndots is 1.
copy_server_list()
make_server(127.0.0.1)
make_server(192.168.168.87)
lock_lookup dighost.c:3750
success
start_lookup()
setup_lookup(0x223a258)
resetting lookup counter.
cloning server list
clone_server_list()
make_server(127.0.0.1)
make_server(192.168.168.87)
using root origin
recursive query
add_question()
starting to render the message
done rendering
create query 0x7fe864505018 linked to lookup 0x223a258
create query 0x7fe864505268 linked to lookup 0x223a258
do_lookup()
send_udp(0x7fe864505018)
bringup_timer()
have local timeout of 1
working on lookup 0x223a258, query 0x7fe864505018
sockcount=1
recving with lookup=0x223a258, query=0x7fe864505018, sock=0x7fe8645054b0
recvcount=1
sending a request
unlock_lookup dighost.c:3752
lock_lookup dighost.c:2398
success
send_done()
sendcount=0
check_if_done()
list empty
unlock_lookup dighost.c:2429
recv_done()
lock_lookup dighost.c:3172
success
recvcount=0
lookup=0x223a258, query=0x7fe864505018
before parse starts
after parse
next_origin()
following up azure.microsoft.ocm
printmessage()
Server:         127.0.0.1
Address:        127.0.0.1#53

** server can't find azure.microsoft.ocm: NXDOMAIN
returning with rcode == 0
still pending.
cancel_lookup()
check_if_done()
list empty
clear_query(0x7fe864505268)
clear_query(0x7fe864505018)
sockcount=0
check_next_lookup(0x223a258)
try_clear_lookup(0x223a258)
destroy
freeing server 0x7fe8580008e8 belonging to 0x223a258
freeing server 0x7fe858001108 belonging to 0x223a258
start_lookup()
check_if_done()
list empty
shutting down
dighost_shutdown()

done, and starting to shut down
cancel_all()
lock_lookup dighost.c:3766
unlock_lookup dighost.c:3651
success
unlock_lookup dighost.c:3809
destroy_libs()
freeing task
freeing taskmgr
lock_lookup dighost.c:3841
success
flush_server_list()
freeing commctx
freeing socketmgr
freeing timermgr
destroy DST lib
detach from entropy
unlock_lookup dighost.c:3894
Removing log context
Destroy memory

Best Answer

dig uses the OS's DNS resolution library. nslookup uses its own, including potentially caching responses like NXDOMAIN. For a while nslookup was considered a deprecated tool to be avoided in favor of other tools like dig. Bind 9.9.0 changed that (text search for 1700.), however, and nslookup is apparently in a slightly-less-sucky state.

What you should do is make sure you have nslookup that was compiled at or after Bind 9.9.0. Then you should ask yourself "Why do I care about nslookup vs dig?" If you don't have a very specific and detailed answer, stick with dig.


Fiiiiiine, if you really want to tweak around with nslookup, you should flush any local resolver's cache, such as ncsd or dnsmasq, or any OS specific DNS cache flushing mechanism such as sudo service dns-clean restart on certain versions of Ubuntu. Specific details of determining if there's even a DNS caching tool on the host, and how to flush it, is left as an exercise for the reader.