DNSSEC Quick Zone Setup with BIND

By Christopher Stone
Published Jan 30, 2014
CC By-SA Licensed
Setting up DNSSEC for your zones can be a daunting task with the lack of short and clear guides. This article is simply how to get running with the least effort possible. I'm setting this up on a FreeBSD 9.x system, which comes with BIND 9.8.1 or later; FreeBSD 10.0 and later versions come with UNBOUND (I'm not sure if the commands are the same or not).

I've left out as much explanation of what's going as possible. If you have questions about how DNSSEC works or what any of these commands are doing in detail there are copious amounts of data on the Internet. Also, I'm using flat files, and they keys are just getting dumped in the same "master" directory as the zone file. This works for very simple setups, but I would not recommend organizing a large site this way.
Before starting make sure your TLD and Registrar support DNSSEC. If they don't support it this is all for naught. Also, I don't own the example.com domain, so some of the following is representative of the output you should see, but not the real output of exact commands shown.

Create your Zone Keys

Create the "Key Signing Key", this should be a reasonably good key and doesn't get used/transmitted much.
root@aislynn# dnssec-keygen -f KSK -a RSASHA1 -b2048 -n ZONE example.com
Generating key pair........+++ ...............................+++
Kexample.com.+005+51367
Create the "Zone Signing Key", this one signs everything, since it is used constantly you do not want it to be too big. If you are concerned about security you should change this key regularly.
root@aislynn# dnssec-keygen -a RSASHA1 -b 768 -n ZONE example.com
Generating key pair......++++++++ ......++++++++
Kexample.com.+005+09261
You should now have four new files, two public and two private keys.
root@aislynn# lc
-rw-r--r--  1 root  wheel   389B Jan 30 20:03 Kexample.com.+005+09261.key
-rw-------  1 root  wheel   802B Jan 30 20:03 Kexample.com.+005+09261.private
-rw-r--r--  1 root  wheel   605B Jan 30 20:00 Kexample.com.+005+51367.key
-rw-------  1 root  wheel   1.8k Jan 30 20:00 Kexample.com.+005+51367.private

Update your Zone File

Include the created public keys in your existing zone file, something like this:
@	IN SOA	ns1.example.com. root.example.com. (
				2014013001	; serial
				2h		; refresh
				1h		; retry
				1w		; expire
				2h		; minimum
				)
				
			NS	ns1.example.com
ns1			A	192.0.2.5

$INCLUDE	master/Kexample.com.+005+51367.key
$INCLUDE 	master/Kexample.com.+005+09261.key

@		IN	A	192.0.2.1
*		IN	A	192.0.2.1
Sign your zone file. This generates a new "signed" version. Keep the unsigned version, update it whenever necessary and repeate the signing processes to generate a new signed version each time.
root@aislynn# dnssec-signzone -o example.com -k master/Kexample.com.+005+51367.key \
	master/example.com master/Kexample.com.+005+09261.key
dnssec-signzone: warning: example.com:1: no TTL specified; using SOA MINTTL instead
Verifying the zone using the following algorithms: RSASHA1.
Zone fully signed:
Algorithm: RSASHA1: KSKs: 1 active, 0 stand-by, 0 revoked
                    ZSKs: 1 active, 0 stand-by, 0 revoked
example.com.signed
Make sure you pass the KSK (first, longer) key to the '-k' arguement, and the ZFS (second, shorter) key at the end. The "warning" is a red herring of sorts.

Edit your 'named.conf' or whever the zone is specified, make sure you are pulling from the "signed" file and not the original. Something like:
zone "example.com" {
        type master;
        file "master/example.com.signed";
};

Create the DN Fingerprint and Upload

The world needs to know your fingerprint, otherwise any server could be serving signed DNS records.
root@aislynn# dnssec-dsfromkey -1 -f example.com.signed example.com
example.com. IN DS 51367 5 1 527EE9DED3B1DC3F7FE9C7F3CE08E8E56674D6A8
You're registrar will have a page where you can "upload" this information. There are 4 key pieces of information from that output. The Key Tag is the 5 digit number, "51367" in this example. The Algorithm is the next number "5". The Digest Type is the next number "1". Finally the Digest is the long hex string at the end. You can also specify and expiration or maximum life, but we have not done so in this example.

Verification

Registrars are usually right on top of updates, but it might take a few hours before you can verify your configuration. If it's still failing after a day contact their support to see what is holding up the process. For a basic verification that signed records are accessible:
root@aislynn# dig +dnssec +short example.com
192.0.2.1
A 5 2 1209600 hrTQPRZKmLnU4MdiaqLfeiNyYFI/PA4Ym8tI H5ZnPBRAaFpEnFwKRiF26zm7rRLDTFOQnqL3 TS6PQjuBXm+c3gyg4D8t
TO+uqknn+v4FCxIw FVgwMq5TBzYsLnJvyBgH
For a complete verification at every level, you first need a copy of the root keys:
root@aislynn# dig . DNSKEY | grep -Ev '^($|;)' > root.keys
You will also need a copy of 'dig' built with the '-DDIG_SIGCHASE' option. You can build a copy from the ports tree (dns/bind-tools) has this as a config option. You can then run:
root@aislynn# dig +dnssec +sigchase +topdown +trusted-key=root.keys example.com
<-- Snipped output: there's a lot of diagnostic details in here -->
;; The Answer:
example.com.               1209600 IN      A       192.0.2.1

;; FINISH : we have validate the DNSSEC chain of trust: SUCCESS

;; cleanandgo
We got the correct Answer and a successful validation of the chain of trust, it's working.

If you don't have dig available you can use Sandia Nation Laboratories' online DNSViz tool to verify a variety of DNS functionality, including DNSSEC. It tends to be a bit slow, so have patience with it. It is the most complete check of DNS functionality I've found online.