There is another flurry of interest in DNS cache poisoning. The first thing that you should do is turn off recursion if you don’t need it. One way to determine this is with DiG:
$ dig -v DiG 9.5.0-P2 $ |
Verizon operates a well known server that does recursive lookups:
$ dig @4.2.2.3 example.com ; <<>> DiG 9.5.0-P2 <<>> @4.2.2.3 example.com ; (1 server found) ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7292 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;example.com. IN A ;; ANSWER SECTION: example.com. 38163 IN A 208.77.188.166 ;; Query time: 10 msec ;; SERVER: 4.2.2.3#53(4.2.2.3) ;; WHEN: Sun Aug 3 08:33:06 2008 ;; MSG SIZE rcvd: 45 |
Let’s try another domain that we know is hosted on a server that doesn’t support recursion:
$ dig @4.2.2.3 sysadmintools.com ; <<>> DiG 9.5.0-P2 <<>> @4.2.2.3 sysadmintools.com ; (1 server found) ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64056 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;sysadmintools.com. IN A ;; ANSWER SECTION: sysadmintools.com. 43200 IN A 72.51.38.109 ;; Query time: 18 msec ;; SERVER: 4.2.2.3#53(4.2.2.3) ;; WHEN: Sun Aug 3 08:33:15 2008 ;; MSG SIZE rcvd: 51 |
That’s as expected. Let’s find out the authoritative server:
$ dig @4.2.2.3 sysadmintools.com ns ; <<>> DiG 9.5.0-P2 <<>> @4.2.2.3 sysadmintools.com ns ; (1 server found) ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28133 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;sysadmintools.com. IN NS ;; ANSWER SECTION: sysadmintools.com. 43185 IN NS ns1.geodns.net. sysadmintools.com. 43185 IN NS ns2.geodns.net. ;; Query time: 10 msec ;; SERVER: 4.2.2.3#53(4.2.2.3) ;; WHEN: Sun Aug 3 08:33:30 2008 ;; MSG SIZE rcvd: 81 |
For kicks, let’s dig by address on this one:
$ ping ns1.geodns.net PING ns1.geodns.net (69.28.203.75) 56(84) bytes of data. --- ns1.geodns.net ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0ms $ dig @69.28.203.75 sysadmintools.com ; <<>> DiG 9.5.0-P2 <<>> @69.28.203.75 sysadmintools.com ; (1 server found) ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25396 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2 ;; WARNING: recursion requested but not available ;; QUESTION SECTION: ;sysadmintools.com. IN A ;; ANSWER SECTION: sysadmintools.com. 86400 IN A 72.51.38.109 ;; AUTHORITY SECTION: sysadmintools.com. 86400 IN NS ns2.geodns.net. sysadmintools.com. 86400 IN NS ns1.geodns.net. ;; ADDITIONAL SECTION: ns1.geodns.net. 92966 IN A 69.28.203.75 ns2.geodns.net. 108198 IN A 72.51.32.75 ;; Query time: 71 msec ;; SERVER: 69.28.203.75#53(69.28.203.75) ;; WHEN: Sun Aug 3 08:34:18 2008 ;; MSG SIZE rcvd: 129 |
As expected. The authoritative DNS server should answer queries for its domains. Let’s do a recursive query, one that tries to resolve example.com:
$ dig @69.28.203.75 example.com ; <<>> DiG 9.5.0-P2 <<>> @69.28.203.75 example.com ; (1 server found) ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20006 ;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 0 ;; WARNING: recursion requested but not available ;; QUESTION SECTION: ;example.com. IN A ;; AUTHORITY SECTION: com. 163983 IN NS f.gtld-servers.net. com. 163983 IN NS g.gtld-servers.net. com. 163983 IN NS h.gtld-servers.net. com. 163983 IN NS i.gtld-servers.net. com. 163983 IN NS j.gtld-servers.net. com. 163983 IN NS k.gtld-servers.net. com. 163983 IN NS l.gtld-servers.net. com. 163983 IN NS m.gtld-servers.net. com. 163983 IN NS a.gtld-servers.net. com. 163983 IN NS b.gtld-servers.net. com. 163983 IN NS c.gtld-servers.net. com. 163983 IN NS d.gtld-servers.net. com. 163983 IN NS e.gtld-servers.net. ;; Query time: 71 msec ;; SERVER: 69.28.203.75#53(69.28.203.75) ;; WHEN: Sun Aug 3 08:34:27 2008 ;; MSG SIZE rcvd: 253 $ |
This is what happens when recursion is turned off. Let’s prove it by quering a local server with recursion turned off:
$ dig @localhost example.com ; <<>> DiG 9.5.0-P2 <<>> @localhost example.com ; (1 server found) ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47368 ;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 0 ;; WARNING: recursion requested but not available ;; QUESTION SECTION: ;example.com. IN A ;; AUTHORITY SECTION: . 518400 IN NS C.ROOT-SERVERS.NET. . 518400 IN NS J.ROOT-SERVERS.NET. . 518400 IN NS I.ROOT-SERVERS.NET. . 518400 IN NS E.ROOT-SERVERS.NET. . 518400 IN NS F.ROOT-SERVERS.NET. . 518400 IN NS M.ROOT-SERVERS.NET. . 518400 IN NS H.ROOT-SERVERS.NET. . 518400 IN NS G.ROOT-SERVERS.NET. . 518400 IN NS L.ROOT-SERVERS.NET. . 518400 IN NS B.ROOT-SERVERS.NET. . 518400 IN NS A.ROOT-SERVERS.NET. . 518400 IN NS D.ROOT-SERVERS.NET. . 518400 IN NS K.ROOT-SERVERS.NET. ;; Query time: 0 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Sun Aug 3 08:36:25 2008 ;; MSG SIZE rcvd: 240 |
The setting to control this with BIND are in /etc/named.conf in the global section (options):
$ options { directory "/var/named/chroot/var/named"; pid-file "/var/run/named/named.pid"; # recursion no; }; |
Let’s restart BIND (named) and try again:
$ dig @localhost example.com ; <<>> DiG 9.5.0-P2 <<>> @localhost example.com ; (1 server found) ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8828 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2 ;; QUESTION SECTION: ;example.com. IN A ;; ANSWER SECTION: example.com. 172800 IN A 208.77.188.166 ;; AUTHORITY SECTION: example.com. 172800 IN NS a.iana-servers.net. example.com. 172800 IN NS b.iana-servers.net. ;; ADDITIONAL SECTION: a.iana-servers.net. 172800 IN A 192.0.34.43 b.iana-servers.net. 172800 IN A 193.0.0.236 ;; Query time: 164 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Sun Aug 3 08:38:30 2008 ;; MSG SIZE rcvd: 125 $ |
Let’s change it back by removing the # and restarting BIND:
$ dig @localhost example.com ; <<>> DiG 9.5.0-P2 <<>> @localhost example.com ; (1 server found) ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62534 ;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 0 ;; WARNING: recursion requested but not available ;; QUESTION SECTION: ;example.com. IN A ;; AUTHORITY SECTION: . 518400 IN NS F.ROOT-SERVERS.NET. . 518400 IN NS C.ROOT-SERVERS.NET. . 518400 IN NS B.ROOT-SERVERS.NET. . 518400 IN NS L.ROOT-SERVERS.NET. . 518400 IN NS J.ROOT-SERVERS.NET. . 518400 IN NS E.ROOT-SERVERS.NET. . 518400 IN NS M.ROOT-SERVERS.NET. . 518400 IN NS D.ROOT-SERVERS.NET. . 518400 IN NS I.ROOT-SERVERS.NET. . 518400 IN NS H.ROOT-SERVERS.NET. . 518400 IN NS A.ROOT-SERVERS.NET. . 518400 IN NS K.ROOT-SERVERS.NET. . 518400 IN NS G.ROOT-SERVERS.NET. ;; Query time: 0 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Sun Aug 3 08:40:48 2008 ;; MSG SIZE rcvd: 240 $ |