If you are searching for a DNSSEC validating DNS server, you can use BIND to do that. In fact, with a current version of BIND, e.g. version 9.10, the dnssec-validation is enabled by default. If you are already using BIND as a recursive or forwarding/caching server, you’re almost done. If not, this is a very basic installation guide for BIND with DNSSEC validation enabled and some notes on how to test it.
I am using a fresh Ubuntu 16.04 LTS installation with BIND 9.10.3-P4, that is:
sudo apt-get update sudo apt-get install bind9 sudo service bind9 start
The configuration files are stored in “/etc/bind/“. To allow DNS queries for the local clients, edit the options (
sudo nano named.conf.options), add your subnets, e.g.:
allow-recursion { localhost; 192.168.0.0/16; 2003:51:6012:100::/56; };
and restart the server:
sudo service bind9 restart.
DNSSEC by Default
The interesting part is that the DNSSEC validation is enabled by default. The “dnssec-validation auto;” option is already present and the “dnssec-enable yes;” option is not needed, because its default is already “yes”. (See here: DNS BIND Security Statements.)
Furthermore, the directory option is already present, too:
directory "/var/cache/bind";
That is, the managed keys are stored here:
/var/cache/bind/managed-keys.bind.
Test with Dig
A basic test with dig against a DNSSEC secured domain will show the “ad” flag (authenticated data, see DNS Header Flags), in the header:
weberjoh@jw-nb12:~$ dig weberdns.de ; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> weberdns.de ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34885 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;weberdns.de. IN A ;; AUTHORITY SECTION: weberdns.de. 180 IN SOA ns1.weberdns.de. webmaster.weberdns.de. 2016051901 14400 1800 604800 180 ;; Query time: 19 msec ;; SERVER: 192.168.120.22#53(192.168.120.22) ;; WHEN: Thu May 19 14:03:59 CEST 2016 ;; MSG SIZE rcvd: 90
More relevant, a failure in a DNSSEC secured domain will result in a SERVERFAIL without an answer:
weberjoh@jw-nb12:~$ dig sigfail.verteiltesysteme.net ; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> sigfail.verteiltesysteme.net ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 64793 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;sigfail.verteiltesysteme.net. IN A ;; Query time: 58 msec ;; SERVER: 192.168.120.22#53(192.168.120.22) ;; WHEN: Thu May 19 14:04:38 CEST 2016 ;; MSG SIZE rcvd: 57
To test (!) the failure, the cd flag (check disabled) can be sent with dig, which reveals the answer, but of course with the cd flag again and not with the ad flag in the answer:
weberjoh@jw-nb12:~$ dig sigfail.verteiltesysteme.net +cd ; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> sigfail.verteiltesysteme.net +cd ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39420 ;; flags: qr rd ra cd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 5 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;sigfail.verteiltesysteme.net. IN A ;; ANSWER SECTION: sigfail.verteiltesysteme.net. 60 IN A 134.91.78.139 ;; Query time: 20 msec ;; SERVER: 192.168.120.22#53(192.168.120.22) ;; WHEN: Thu May 19 14:04:45 CEST 2016 ;; MSG SIZE rcvd: 197
Online Test for Clients
More interesting for the clients is an online test whether DNSSEC validation works or not. I am using the one at http://dnssec.vs.uni-due.de. If a client uses the just configured BIND server, the test looks like that:
Congrats! You are now validating domain names.
Stats ‘n Cache
To view some statistics of BIND, execute the following shell command:
sudo rndc stats
This appends the statistics into this file:
/var/cache/bind/named.stats. Note the “+++ Statistics Dump +++ (1471872885)” beginning of each new dump, while the number in brackets is the unixtime. In my case, for example, this looks like that:
+++ Statistics Dump +++ (1471872885) ++ Incoming Requests ++ 611719 QUERY ++ Incoming Queries ++ 64716 A 1 NS 131 SOA 484641 PTR 22 MX 40 TXT 61880 AAAA 279 SRV 9 ANY ++ Outgoing Queries ++ [View: default] 140942 A 53 NS 110 CNAME 154 SOA 143244 PTR 23 MX 2 TXT 134638 AAAA 206 SRV 104142 DS 17265 DNSKEY 2 ANY [View: _bind] ++ Name Server Statistics ++ 416710 IPv4 requests received 195009 IPv6 requests received 328 requests with EDNS(0) received 33 TCP requests received 609642 responses sent 46 truncated responses sent 328 responses with EDNS(0) sent 479303 queries resulted in successful answer 89521 queries resulted in authoritative answer 509101 queries resulted in non authoritative answer 29451 queries resulted in nxrrset 11020 queries resulted in SERVFAIL 89868 queries resulted in NXDOMAIN 152697 queries caused recursion 1881 duplicate queries received 196 queries dropped 611686 UDP queries received 33 TCP queries received ++ Zone Maintenance Statistics ++ ++ Resolver Statistics ++ [Common] [View: default] 363641 IPv4 queries sent 177140 IPv6 queries sent 346942 IPv4 responses received 168436 IPv6 responses received 24977 NXDOMAIN received 4212 SERVFAIL received 32 FORMERR received 118 EDNS(0) query failures 34758 truncated responses received 2516 lame delegations received 87670 query retries 26471 query timeouts 69897 IPv4 NS address fetches 72415 IPv6 NS address fetches 870 IPv4 NS address fetch failed 41590 IPv6 NS address fetch failed 249786 DNSSEC validation attempted 123250 DNSSEC validation succeeded 125845 DNSSEC NX validation succeeded 177 DNSSEC validation failed 180114 queries with RTT < 10ms 223124 queries with RTT 10-100ms 104360 queries with RTT 100-500ms 5988 queries with RTT 500-800ms 1457 queries with RTT 800-1600ms 83 queries with RTT > 1600ms 31 bucket size 7363 REFUSED received [View: _bind] 31 bucket size ++ Cache Statistics ++ [View: default] 5706174 cache hits 3570 cache misses 996705 cache hits (from query) 933523 cache misses (from query) 0 cache records deleted due to memory exhaustion 414200 cache records deleted due to TTL expiration 18385 cache database nodes 8319 cache database hash buckets 11143805 cache tree memory total 7815275 cache tree memory in use 8389020 cache tree highest memory in use 655360 cache heap memory total 263168 cache heap memory in use 271360 cache heap highest memory in use [View: _bind (Cache: _bind)] 0 cache hits 0 cache misses 0 cache hits (from query) 0 cache misses (from query) 0 cache records deleted due to memory exhaustion 0 cache records deleted due to TTL expiration 0 cache database nodes 64 cache database hash buckets 287392 cache tree memory total 29608 cache tree memory in use 29608 cache tree highest memory in use 262144 cache heap memory total 1024 cache heap memory in use 1024 cache heap highest memory in use ++ Cache DB RRsets ++ [View: default] 4045 A 5685 NS 102 CNAME 3751 PTR 1300 AAAA 455 DS 3380 RRSIG 1963 NSEC 301 DNSKEY 4 !A 214 !AAAA 1135 !DS 240 NXDOMAIN [View: _bind (Cache: _bind)] ++ ADB stats ++ [View: default] 1021 Address hash table size 4710 Addresses in hash table 1021 Name hash table size 3925 Names in hash table [View: _bind] 1021 Address hash table size 1021 Name hash table size ++ Socket I/O Statistics ++ 341815 UDP/IPv4 sockets opened 164252 UDP/IPv6 sockets opened 21867 TCP/IPv4 sockets opened 12897 TCP/IPv6 sockets opened 1 Raw sockets opened 341813 UDP/IPv4 sockets closed 164251 UDP/IPv6 sockets closed 21866 TCP/IPv4 sockets closed 12928 TCP/IPv6 sockets closed 36 UDP/IPv4 socket bind failures 6 UDP/IPv6 socket bind failures 21 TCP/IPv6 socket connect failures 341777 UDP/IPv4 connections established 164245 UDP/IPv6 connections established 21699 TCP/IPv4 connections established 12822 TCP/IPv6 connections established 3 TCP/IPv4 connections accepted 33 TCP/IPv6 connections accepted 252 UDP/IPv4 recv errors 1 TCP/IPv6 recv errors 2 UDP/IPv4 sockets active 1 UDP/IPv6 sockets active 6 TCP/IPv4 sockets active 35 TCP/IPv6 sockets active 1 Raw sockets active ++ Per Zone Query Statistics ++ --- Statistics Dump --- (1471872885)
To view the current cache of BIND, run the following command:
sudo rndc dumpdb -cache
This dumps the whole cache into this file:
/var/cache/bind/named_dump.db.
It can be listed/grepped as normal, e.g.:
weberjoh@jw-vm08-int-dns:/var/cache/bind$ cat named_dump.db | grep ubuntu ubuntu.com. 172675 NS ns1.p27.dynect.net. de.archive.ubuntu.com. 492 CNAME ubuntu.mirror.tudos.de. ntp.ubuntu.com. 475 A 91.189.89.198 security.ubuntu.com. 492 A 91.189.88.149 ubuntu.mirror.tudos.de. 10692 \-AAAA ;-$NXRRSET 0.ubuntu.pool.ntp.org. 1371 \-AAAA ;-$NXRRSET 1.ubuntu.pool.ntp.org. 1372 \-AAAA ;-$NXRRSET 2.ubuntu.pool.ntp.org. 23 A 5.9.80.113 3.ubuntu.pool.ntp.org. 1374 \-AAAA ;-$NXRRSET
Final notes: A much more detailed post about BIND as a caching server is here. And yes, I know that some security people don’t like the usage of BIND for a mere forwarding DNS server. The blog post about Unbound is coming soon. Cheers.