Configuring DNSSEC on EL6 and bind 9

It looks like there isn’t much in the way of documentation to step people through enabling DNSSEC on their Scientific Linux 6 / CentOS 6 / RHEL6 servers – so as I normally do, I’ve decided to write a quick howto based on MANY searches and trial and error.

1) Firstly, we need to enable dnssec in /etc/named.conf. This will enable the DNSSEC feature set in bind. Check you have the following, or add it if it doesn’t exist:
options {
dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;
}

Restart bind after this via service named restart.

2) Next, we want to go to where your DNS zone file is. I’ve used my domain in this example. We now want to create the Zone Key (ZSK). The directories below will probably be different for your system. It will also take quite a while.
# cd /var/named/chroot/var/named/master
# dnssec-keygen -a RSASHA1 -b 1024 -n ZONE crc.id.au

This will create two files:

  • Kcrc.id.au.*.key (public key)
  • Kcrc.id.au.*.private (private key)

3) Now we need to create the Secure Entry Key (KSK) for the domain. It also takes quite a while. Go grab a coffee after starting this. Or two.
# dnssec-keygen -a RSASHA1 -b 4096 -n ZONE -f KSK crc.id.au

4) To make the zones use DNSSEC, we need to now add ONLY the public portions of the generated keys to the zone file.
# cat Kcrc.id.au*.key >> crc.id.au

WARNING: For the love of $DEITY, make sure you use >> here so you don’t wipe out your zone file!

5) Next up, signing the zone file and adding the fields required:
# dnssec-signzone -e +3024000 -­N INCREMENT crc.id.au

This signs to zone file with an end time 35 days after the start time. This allows you to automatically resign the domain using a script in /etc/cron.monthly without the domain expiring after 30 days (the default). This will also increment the serial on the zone file automatically (so you don’t forget!).

The result, will be the output file crc.id.au.signed.

6) We now have to tell bind to use the new signed zone file in /etc/named.conf. We want to replace the entry that currently refers to the non-signed zone file (crc.id.au) for the signed zone file (crc.id.au.signed).
zone "crc.id.au" {
file "/var/named/master/crc.id.au.signed";
};

7) We are now ready to restart bind to activate the new signed config.
# service named reload

8) Now – this is the tricky part. At the time of writing, AusRegistry does not support DNSSEC for .au domains. You now need to provide your KSK to your registrar to create a chain-of-trust. For people who have non-.au domain names, this should be possible. For .au domain names, well, you’re out of luck until AusRegistry pulls its finger out.

Things to be aware of:
1) By default, zone signatures (dnssec-signzone) expire 30 days after the last time they are generated. This tutorial extends this to 35 days to allow you to use a cron to resign the zonefile in the monthly cron. I use a script as follows:
#!/bin/bash
SIGNZONE="/usr/sbin/dnssec-signzone"
cd /var/named/chroot/var/named/master
$SIGNZONE -n INCREMENT crc.id.au
service named reload

If you put this script in /etc/cron.monthly/, your zones will be automatically resigned every month.

2) Every time you change a zone file, you have to re-sign it. This can be scripted – however I still do this manually.

3) The current best practice is to generate a new KSK every year, and a new ZSK every 3 months. This is pretty much repeating this guide from step 1. It can probably be scripted – as long as you don’t double up on the public keys being placed in the zone file (step 4).