DNSSEC made easy: Converting an existing DNS zone to Inline signing with BIND


DNSSECDNSSEC — the security extensions to the trusty Domain Name System (DNS) upon which almost all Internet transactions rely — is often considered hard to set up. My own setup has been very dated, using complicated scripts which needed to run after every change to the zone file. There was time to change this. Modern versions of the BIND make this rather easy, as I found out.

Background

DNSSEC extends DNS with security; namely authenticity. With proper authenticity, much more information can be stored there, such as which encryption key an authentic server for a particular domain is expected to present when establishing a connection. DANE (DNS-based Authentication of Named Entities), the mechanism that achieves this by adding TLSA (Transport Layer Security Authentication) records into DNS. But also other entries, such as ssh keys in SSHFP entries, or SPF and DKIM values should not be trusted unless stored in DNSSEC.

My old setup was based on running dnssec-signzone as part of a regular script, together with some fancy include-file processing. This was not easy to set up and maintain. It was time to change this. Luckily, BIND has matured a lot in these years since manually creating my setup based on the HOW-TOs available at the time. Here is how to run DNSSEC today.

Activating DNSSEC today

Let me explain how one would do this today on Linux (the examples are from an Ubuntu installation). We assume there to be already an (unsigned) domain example.ch with the following configuration entry in /etc/bind/named.conf.local:

zone "example.ch" { type master; file "/etc/bind/example.ch.zone"; };

First, we need to move that file to /var/lib/bind/example.ch.zone, and the configuration line updated to read as follows:[1]dnssec-secure-to-insecure yes;” is not required for normal operation, but is nice if you want to temporarily go back to an unsigned zone by issuing “nsupdate -l⏎delete example.ch dnskey⏎send⏎quit“, in case you want to try again. Update 2018-02-10: This DNSKEY deletion procedure needs to be followed as well when importing a zone file which has already been manually signed before.

zone "example.ch" { type master; file "/var/lib/bind/example.ch.zone"; update-policy local; auto-dnssec maintain; dnssec-secure-to-insecure yes; };

This gives named permission to perform it’s magic on the zone [2]the default apparmor configuration for Ubuntu prevents named from modifying anything in /etc/bind, only in /var/lib/bind (and /var/cache/bind, meant for slave zones.

Next, we need to let named know about DNSSEC. Add the following lines to /etc/bind/named.conf.options, in the options {}; block, maybe right after dnssec-validation auto;:

dnssec-enable yes;
key-directory "/etc/bind/key";

Note that $INCLUDE, $GENERATE and similar statements in your zone files will be replaced by the contents they expanded to when signing was activated. Given that you now have dynamic updates available, this might obviate such statements anyway.

If you rely on including other dynamic files, this procedure is not for you!

Make sure you have a backup of these files, if you are unsure or they contain valuable data. It is good practice to put such files into a version management system such as subversion or git.

Adding -a RSASHA256 -b 2048 to the first dnssec-keygen command below is commonly recommended; there are even DNS registars which will only accept that key type. If you have the option, I recommend using ECDSA by adding -a ECDSAP256SHA256 to this command, and, if your registrar supports it, also to the second command.[3]Update 2018-02-10: If you later need to change the encryption algorithm, please follow these instruction.

# mkdir /etc/bind/keys
# cd /etc/bind/keys
# dnssec-keygen -3 example.ch # Create the (short-term) key to sign the entries
Generating key pair.
Kexample.de.+013+64514
# dnssec-keygen -3 -fk example.ch # Create the (long-term) key to sign the above signing key
Generating key pair.................................+++ ........+++
Kexample.de.+007+62928
# chown bind:bind * # Ensure they can be read by named
# rndc loadkeys example.ch # Let BIND know about them
# rndc signing -nsec3param 1 0 10 `od -Anone -tx4 -N4 /dev/urandom` example.ch # Enable NSEC3 and set a random mixing value ("salt") 
# rndc signing -list example.ch # Show signing status
Done signing with key 62928/NSEC3RSASHA1
Done signing with key 64514/ECDSAP256SHA256

If you do not want NSEC3 or do not need it, you can also skip the rndc signing -nsec3param … command above or undo it with rndc signing -nsec3param none.

To fully enable DNSSEC, all there remains is to register the Zone Signing Key (ZSK, the one you created with -fk above) with your DNS registrar. The information you need is in Kexample.de.+007+62928.key, the file name printed as part of the key generation.

Be aware, that you have a dynamic zone now, i.e., any necessary changes are stored in the *.jnl file in the same directory. Changes to the *.zone file will be ignored. If you want to make modifications to the file, enclose the editing process in rndc freeze/thaw, as follows:

# rndc freeze example.ch
# vi /var/lib/bind/example.ch.zone # Don't forget to increment the SOA serial!
# rndc thaw example.ch

References

The following web pages provided inspiration for this article (the missing chmod provided ample reason for transpiration):

Instructions and caveats when you plan to change the DNSSEC algorithm used.

Let’s stay in touch!

Receive a mail whenever I publish a new post.

About 1-2 Mails per month, no Spam.

Follow me on the Fediverse

Web apps


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.