Implementing & Maintaining DNSSEC On Bind9 Nameservers

Want to help support this blog? Try out Oh Dear, the best all-in-one monitoring tool for your entire website, co-founded by me (the guy that wrote this blogpost). Start with a 10-day trial, no strings attached.

We offer uptime monitoring, SSL checks, broken links checking, performance & cronjob monitoring, branded status pages & so much more. Try us out today!

Profile image of Mattias Geniar

Mattias Geniar, July 12, 2010

Follow me on Twitter as @mattiasgeniar

I won’t be going into detail what DNSSEC is, and what it does. This only covers the implementation (deployment) and maintenance that accompanies DNSSEC. Here’s the small index of topics I’ll cover.

  1. What is DNSSEC?
  2. Enabling DNSSEC in your environment
  3. Generating your keys: Key Signing Key (KSK) and Zone Signing Key (ZSK)
  4. Adding the public keys to your zone
  5. Signing the zone
  6. Key rotation, zone maintenance
  7. Summary
  8. Links, Articles & Video

There are a few assumptions throughout this article, mostly related to directory structures as I like to keep things organized. Another method would be to create a directory per zone, and store all data within that directory. In reality, that last method would probably be the way to go – this is just for demonstation.

  1. I’m doing the signing for the dummy host “dns.org
  2. I have my zonefiles stored in /var/named/zones/
  3. I have my Key Signing Keys stored in /var/named/KSK
  4. I have my Zone Signing Keys stored in /var/named/ZSK
  5. I have my Delegation Signer and Keyset stored in /var/named/SET

1) What is DNSSEC?

Here are a few links that very accurately explain DNSSEC.

2) Enabling DNSSEC in your environment

For my examples, I’ll be signing the zone “dns.org", for which my nameserver has been configured to be authoritive. To enable DNSSEC, you’ll need to add the following to your /etc/named.conf file. Note; this is only supported in Bind version 9.3 and upwards. For the more advanced features of DNSSEC, you’ll need Bind 9.7 and upwards.

# named -v
BIND 9.3.6-P1-RedHat-9.3.6-4.P1.el5_4.2

So, edit the file /etc/named.conf and add the lines in bold to the options-section.

options {
   ...
   // DNSSEC
   dnssec-enable yes;
};

3) Generating keys: Key Signing Key (KSK) and Zone Signing Key (ZSK)

Just a small clarification on what the KSK and ZSK actually are.

ZSK: Zone Signing Key – this key will sign your records in your zonefile.

KSK: Key Signing Key – this key will sign your Zone Signing Key. This is generally a key with greater key size.

In my set-up, I have all my zones in seperate files located in /var/named/zones/*. I’ll be storing my keys in seperate folders, to keep the overview.

  • /var/named/ZSK: all zone signing keys
  • /var/named/KSK: all key signing keys

Note; ideally, you would want to store your keys on a offline machine, sign your zones there, and transfer them to your online nameserver. However, in set-ups where zones are reconfigured daily, this would cause too much overhead.

First, we’ll generate the Zone Signing Key for dns.org:

# cd /var/named/ZSK
# dnssec-keygen -r /dev/urandom -a RSASHA1 -b 1024 -n ZONE dns.org

This will generate 2 files, using the same naming format: K..key (ie:  Kdns.org.+005+03486.key) __and K..private (ie: Kdns.org.+005+03486.private). The first file holds the public key, and the .private file holds our private key.

Now, to generate the Key Signing Key for dns.org:

# cd /var/named/KSK
# dnssec-keygen -r /dev/urandom -a RSASHA1 -b 4096 -n ZONE -f KSK dns.org

This will also generate 2 files, using the same naming format as the ZSK.

Note; every time you generate a KSK or a ZSK, it will assign a new random ID to the filename.

4) Adding the public keys to your zone

After having generated the KSK and ZSK, we need to add the public key of each file to the zone. In my environment (using the folders described above), this would mean:

# cat /var/named/ZSK/Kdns.org.*.key >> /var/named/zones/dns.org
# cat /var/named/KSK/Kdns.org.*.key >> /var/named/zones/dns.org

This will add the appropriate public key to my zone. I’ve used the wildcard “Kdns.org.*.key” because we can’t predict the ID. However, if you regenerate your keys, you’ll have multiple files that would be added with that wildcard (as there are multiple public keys), so be cautious to remove the “old” public and private keys first.

If you take a look at your zonefile now, you’ll see there are now 2 extra DNSKEY records which have been added.

dns.org. IN DNSKEY 256 3 5 "random chars"
dns.org. IN DNSKEY 257 3 5 "random chars"

The first DNSKEY, with the number “256”, is the smaller Zone Signing Key, with the actual key appended at the back. The second DNSKEY with number “257” is the larger Key Signing Key with the actual key at the end.

After you’ve restarted your nameserver (to activate the newly updated zone) you can check if the records were added OK by trying to query for them:

# dig @localhost DNSKEY dns.org

The ANSWER SECTION should give you 2 DNSKEY’s.

5) Signing the zone

To sign the zone, we need the command to point at the zonefile, the ZSK and KSK.

# cd /var/named/SET
# dnssec-signzone -o dns.org -k /var/named/KSK/Kdns.org.+005+48967.key /var/named/zones/dns.org /var/named/ZSK/Kdns.org.+005+03486.key

Let’s break this down. The first parameter, “– 0", tells us which zone to sign (in this case, dns.org). The second parameter, “– k", allows us to point at the Key Signing Key. Next up is the location of our zonefile, followed by the location of the Zone Signing Key.

Note; the IDs in the filenames will vary for your set-up.

Afterwards, you’ll notice there are now 2 extra files generated in the /var/named/SET directory. First is “dsset-dns.org.", followed by “keyset-dns.org.". I’ve placed these in a seperate directory on purpose, to keep the overview in the /var/named/zones directory.

You’ll also notice that in /var/named/zones, beside the already existing “dns.org” file, there is now also a file called “dns.org.signed” which holds the signed version of the zonefile. It’s also much larger than the original zonefile, because all RRs (Resource Records) are now signed. For reference, here is the original zonefile, the zonefile with dnskey, and the fully signed zonefile.

Now we can change our named.conf to point at the “.signed” version to load this signed zone.

zone "dns.org" IN {
  type master;
  file "/var/named/zones/dns.org.signed";
};

And reload your nameserver to test the newly signed zone.

# dig @localhost dns.org +dnssec

You’ll notice every record is now accompanied by a RRSIG Resource Record as well, which holds the signed version of that Resource Record you requested.

After you’ve signed the zone, you need to pass the public Key Signing Key to the registry, so they can add the necessary DS records to the top level domain.

6) Key rotation, zone maintenance

A) Once a zone has been signed, the RRSIG‘s will have a lifespan of 30 days. After these 30 days, the signatures will expire and cause zones to no longer validate. The only method to “reset” that 30 day timer, is to resign your zones (see step 5 above).

B) Whenever you modify the zone, to add/modify/remove records, you will also have to resign the original zonefile, to re-generate the .signed version.

C) You should re-generate your KSK and ZSK on time. It’s advised to re-generate the KSK every year, and the ZSK every 3 months. The longer the key has been in existance, the greater the chance it’s been “compromised”. To do so, delete the old key (public & private), and re-generate using step 3 of this article.

7) Summary

All in all, enabling DNSSEC for one zone comes down to:

  1. Generate a ZSK and KSK (per zone) using dnssec-keygen
  2. Include those keys into your zonefile
  3. Sign the zone using dnssec-signzone
  4. Load your signed zonefile
  5. Reload the zone or nameserver
  6. Publish your Key Signing Key to the registry

8) Links, Articles & Video

I managed to implement DNSSEC fairly simply, because the following information was made available on the web which explained it very well.

If you’d like to add something, please use the comments below. If I’ve missed some vital information, or published some awful mistake, please let me know.



Want to subscribe to the cron.weekly newsletter?

I write a weekly-ish newsletter on Linux, open source & webdevelopment called cron.weekly.

It features the latest news, guides & tutorials and new open source projects. You can sign up via email below.

No spam. Just some good, practical Linux & open source content.