Batch DNSSEC domain configuration with BIND

reading time ( words)

This post collects some of my notes in quickly configuring sets of domain names for DNSSEC using BIND9. There are many in-depth tutorials on setting up DNSSEC, so this is just my notes on how I deal with groups of tens to hundreds of domains at a time.


These are the important locations where I keep my zone files, keys and DS sets. I keep my DS sets handy because this makes it easier to later add the DS records at my favorite domain registrar.

export ZONEDIR=/var/cache/bind/P
export KEYDIR=/etc/bind/keys
export DSSETS=/etc/bind/dsset

I’ll also create a /tmp/domains file with the list of domain names I’ll be working on this session, one per line. This will make the steps below immensely easier.

Key material preparation

BIND comes equipped with tools to manage all aspects of zone and key file generation. On this step I’ll create the Key Signing Keys and DS sets automatically. Notice the use of /dev/urandom for speed. For more sensitive applications you might want to consider using a better entropy source.

xargs -L1 dnssec-keygen -K ${KEYDIR} -a ECDSAP256SHA256 -b 2048 -f KSK -r /dev/urandom < /tmp/domains
    # <names of the KSK key files>
for d in `cat /tmp/domains`; do for k in ${KEYDIR}/K${d}*.key; do grep key-signing $k 2>/dev/null && dnssec-dsfromkey $k >> ${DSSETS}/dsset-${d}.; done; done
    # <key-signing key logs go by>

After the KSKs have been generated, you need to prepare the ZSKs. The process is similar.

xargs -L1 dnssec-keygen -K ${KEYDIR} -a ECDSAP256SHA256 -b 2048 -r /dev/urandom < /tmp/domains
    # <names of the ZSK key files>

Now ensure that the newly generated key files have adequate permissions so that BIND can work with them.

chown bind:bind ${KEYDIR}/K*

Upload the DS sets to your registrar

This is a good time to upload the DS records to your registrar. That way, the information will propagate to the name servers while we continue with the steps. Each registrar has a way to do this – the key here is to take the DS records from the dsset- files we prepared earlier and associate them with the domains.

Also make sure that the DNS servers are delegated to your name servers. Ask me how I know.

Zone file preparation

I usually pick a domain zone that is close to what I need for my new batch. It may look somewhat like this:

$TTL    7200
@       IN      SOA (
   2017090200           ; Serial
   86400                ; Refresh
   3600                 ; Retry
   604800               ; Expire
   604800 )             ; Negative Cache TTL


Of note, there are no key material $INCLUDE or otherwise. I then generate the new zones with a simple command like this:

for z in `cat /tmp/domains`; do cp ${ZONEDIR}/ ${ZONEDIR}/${z}; done

The final step is to add $INCLUDE statements with the right keys. This is easily done like this.

for d in `cat /tmp/domains`; do for keys in ${KEYDIR}/K${d}*.key; do echo '$INCLUDE '$keys >> ${ZONEDIR}/$d; done; done

Configure your BIND instance

You need to add configuration stanzas to both, your master and secondary servers, so that the zones are now available. The master zone declaration on my setup look like this:

zone "" {
  type master;
  file "P/my-zone-file";
  key-directory  "/etc/bind/keys";
  auto-dnssec maintain;
  inline-signing yes;
  update-policy { grant my-ddns-key zonesub ANY; };
  allow-transfer { key "my-xfer-key"; };
  also-notify {

After making the changes, tell bind to reload its configuration

rndc reconfig

Testing your DNSSEC setup

I usually use the Verisign DNSSEC debugger to ensure that a neutral third party is ok with my configuration. A correct configuration should look like this:

This is what you want to see when checking your DNSSEC setup

So with this setup, I can setup one, ten or one hundred zones in my DNS servers in a short time. Do you do these things differently? Reach out and let me know.