DNSSEC - DNS Security

Configuring DNSSEC on BIND

[EDITORIAL NOTE: This document is still very much a work in progress]

Firstly, why look at using DNSSEC?
(The original page is here)

Disadvantages: it needs a little more maintenance and can make the DNS more fragile. There are a number of other negatives, zones get bigger but remember, I’m trying to win you over.

Advantages: Hey, its fun, something new (invented over a decade ago, but co.za was only signed in September 2017!).

Do Nothing: Nope, this won’t work in the long run. If you are a non-DNSSEC aware Registrar and you transfer over a signed Domain – you may find yourself up a creek without a paddle. The Domain won’t work for 40% of the population because some pesky techie has already put a DS record (the digest of a Key Signing Key or KSK) in the co.za zone for this domain. You need to at least know how to remove it. This is going to happen more and more often. The 40% (and increasing) is the percentage of South Africans already using DNSSEC aware resolvers.

Getting more serious, once a Domain (or rather the Zone file) has been DNSSEC Signed, everything inside it is secure. Not only does this mean that lookups are now secured (Looking up "dnssec.co.za" can not be spoofed) but other interesting records like TLSA can be added. Why mention TLSA, its the fingerprint of a Web (or Mail) certificate. It allows software to check that its got to the right Web (or mail) server – which increases security and user trust in the Internet. This is a “good thing”TM to do. ISP’s in Germany use the TLSA for e-mail server certificates to promote that they are better ISP’s than their competition – because it makes traffic flowing to their mail server just a bit more secure.

Convinced? I hope so.

Please though, take baby steps and first check that things work properly on your ‘experimental’ Domains. Eat your own dog food.

DNSSEC Validation for Browsers

Firstly – when things go wrong, you need a way of detecting the (broken DNSSEC) problem. Please install the “DNSSEC Validation” extension into the browser of your choice. If you are using a DNSSEC aware resolver it will give you a white key on a square shaped green background (in Firefox in the URL bar on the right). Go check “dnssec.co.za”, there will also be a white padlock on a circular green background. This is confirming, using the TLSA (DANE) record, that the Web Certificate is indeed the expected certificate. You can modify the DNSSEC Validators config and tell it to use “” for now.

Oh, anything in RED is bad, grey is not configured and orange, not quite working.
Just for fun, look at the top left of this page, if it says "DNSSEC Secured" then you are using a DNSSEC aware Validator to come here. If it doesn't, lets quickly fix that.

Separating Roles

A Nameserver should either be a Resolver or an Authoritative server – not both. BIND 9 unfortunately can play both roles. A DNSSEC aware resolver can never get a DNSSEC secured answer from a Domain that it is authoritative for. Don’t do it. Most other Nameserver software is either Authoritative or Recursive, not both. BIND 10 (currently scrapped) also separated these roles.

Recursive Nameservers are used to hunt down answers often from the ‘root’ downwards. They start with almost no knowledge. They do though cache data for a limited period (often for a day or fraction of a day). They are always restricted to just your users (unless you are Google with

Authoritative Nameservers are where we keep and manage zone files. This data needs to answer anyone on the Internet. The Nameserver though only knows about data in the zones it hosts. If its the source of the zone (the Primary, Master or Hidden Master) , we may also choose to DNSSEC Sign the zones under our control, to make the internet a safer place.

Configuring BIND to be a DNSSEC aware Resolver

Low hanging fruit

If BIND 9.11 is installed from fresh, it is already configured to act as a DNSSEC aware resolver. It is installed with reasonably secure options and usually the only change needed is to relax the default “trusted acl” (Access Control List) so that it will work on your local network (in this example, -and- 2001:42a0::/48).

acl "trusted" {;
In addition, BIND probably needs to listen for incoming queries on all interfaces. The options “listen-on” need to look like:

        listen-on-v6 { any; };
        listen-on { any; };
The DNSSEC configuration entry necessary in the “options” section is:
options {
        dnssec-validation auto;
There are usually a number of other options already configured. With “dnssec-validation” set to “auto”, BIND will use its built-in “root anchor” and will automatically keep it up to date. The server running BIND should only be running recursive DNS services. If your current configuration file includes ZONE definitions, technically BIND services should be split up on to two different servers, one running the Recursive Services and the other running the Authoritative Services.

Now, when you run “dig” - such as “dig dnssec.co.za”, you should see in the flags section of the output is that the ad bit is set – Authenticated Data.

; <<>> DiG 9.11.1-P1 <<>> dnssec.co.za
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26106
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 6

; EDNS: version: 0, flags:; udp: 4096
; COOKIE: d81c8b6350519da5cdaa11e059c0035ef8c640fe07267302 (good)
;dnssec.co.za.			IN	A

dnssec.co.za.		73315	IN	A

dnssec.co.za.		73315	IN	NS	secdns2.posix.co.za.
dnssec.co.za.		73315	IN	NS	secdns1.posix.co.za.
dnssec.co.za.		73315	IN	NS	control.vweb.co.za.

control.vweb.co.za.	73622	IN	A
secdns1.posix.co.za.	79495	IN	A
secdns2.posix.co.za.	65881	IN	A
control.vweb.co.za.	73622	IN	AAAA	2001:42a0::1
secdns1.posix.co.za.	79495	IN	AAAA	2001:42a0::81

;; Query time: 0 msec
;; WHEN: Mon Sep 18 19:33:18 SAST 2017
;; MSG SIZE  rcvd: 266

Configuring BIND to generate DNSSEC Signed Zones – the Authoritative server

The objective here is to have BIND create and maintain as automatically and a simply as possible the DNSSEC for and Signing of a few domains. For this, we use inline signing (BIND talks to itself) and BIND’s new KeyManager, dnssec-keymgr. What is not included is the process of getting the digest of a Key Signing Key (or KSK), that is, the DS Record into the Parent zone.

Installing a fresh copy of BIND 9.11 gives us a working recursive server only working on the localhost (loopback addresses). Using the configuration for a Recursive server, the initial modifications are to turn off “dnssec-validation” and “recursion”.

The changed configurations will look something like:

options {
	allow-recursion { none; };
        dnssec-validation off;

There is also an ACL called “axfr”. This is a list of who can transfer zones and should thus include the identity of your Secondary or Slave authoritative nameservers, such as:

acl "xfer" {;
We also want anyone to be able to query our Authoritative nameserver, so allow queries from anywhere:
	allow-query { any; };
There should be nothing really new up to this point.

BIND 9.11 includes a program called “dnssec-keymgr”. This is a python program and so your server should include python and BIND (named) needs to be compiled with the “python” compile time flag. The “dnssec-keymgr” program will generate “keys” for our zones. In order to generate these keys, the server needs a good source of entropy (randomness) and one suitable method for generating randomness (especially if your server is a virtual server) is to install a program called “haveged”, otherwise key generation will be very, very slow. The default for BIND is to have all the generated keys in one directory. With a number of zones, this can become unmanageable so the author suggests creating a directory based on the zone file and storing all relevant data for that zone in that directory.

Adding the Zone Magic
In the “named.conf” file, there is a Master Zone template. It looks like:
//zone "YOUR-DOMAIN.TLD" {
//      type master;
//      file "/var/bind/pri/YOUR-DOMAIN.TLD.zone";
//      allow-query { any; };
//      allow-transfer { xfer; };
This needs to be modified into something that looks like:
zone "smtp.co.za" {
        type master;
        file "pri/smtp.co.za/db.smtp.co.za";
        key-directory "pri/smtp.co.za";
        inline-signing yes;
        auto-dnssec maintain;
        update-policy { grant ddns-key zonesub ANY; };
Note: The “pri” directory is where we will place all master (primary) nameserver configurations. To simplify management, there will be a directory per zone file and anything to do with that zone file will be stored there, including Keys for that zone.

There is nothing special that needs to be done to an existing zone. You can continue to edit or maintain it in your existing manner. It is assumed that the zone will be named according to the “file” line in the example above.

The “Zone” entry can be repeated for all zones, one zone per directory. Perhaps start with one zone and once working, add a few more as required.

Configuring dnssec-keymgr and friends

The BIND DNSSEC Key Manager (dnssec-keymgr) is designed to be run from “cron” using a “crontab” entry but can be run by hand. It should be run as the BIND user (“named” in my case) so the keys created can be read by BIND. It runs with the assistance of a configuration file which provides the timing requirements for signing and resigning zones. A sample config file for “/etc/dnssec-policy.conf” (the default name) follows:
policy default-dnssec {
    algorithm rsasha256;
    key-size zsk 2048;
    key-size ksk 2560;
    pre-publish zsk 1w;
    post-publish zsk 1w;
    roll-period zsk 1mo;
    roll-period ksk 0;
    coverage 364d;

zone smtp.co.za {
    policy default-dnssec;
    directory "/etc/bind/pri/smtp.co.za";
You’ll need an additional “zone” statement for every zone. Currently, “dnssec-keymgr” does not appear to read the “key” directory from the “named.conf” file.

The default Keysize for a ZSK is 1024 bits. People are beginning to say that's too small hence the 2048 above.
In the same vein, the default size for a KSK is 2048 bits but we have 2560 bits here.

The Key Manager will create Keys owned by whomever runs the program. BIND needs the keys owned by the bind user which on my system is “named”.

Run “dnssec-keymgr” from the command line as the “named” user (su named -c /usr/sbin/dnssec-keymgr). You may have to edit the “/etc/passwd” file to change the “shell”i for “named” to something that works such as “/bin/sh”. Keys will be automatically generated. Additional files will be added. In my example they were:

  • four files starting with the name smtp.co.za- – the private and public ZSK/KSK keys
  • db.smtp.co.za.jbk, db.smtp.co.za.signed, db.smtp.co.za.signed.jnl – the signed zone
Add this command into crontab “crontab -e” to run once an hour:
10 * * * * su named -c /usr/sbin/dnssec-keymgr
This tells “cron” to run the command every hour on every day at 10 minutes past the hour.

Lastly, the KSK (Key Signing Key) needs to be used to generate a DS record (a digest of the KSK) which needs to be placed in the parent to complete the chain of trust. The command:

dig @ smtp.co.za dnskey | dnssec-dsfromkey -2 -f - smtp.co.za
currently gives me:
smtp.co.za. IN DS 17476 8 2 D0999C09698A7A9F5DA91981BD2493717866C3697703A6302736300CB5077BA9
This is the SHA256 digest (the “-2” in the command) and should be accepted by your Parent Domain or Registrar. Once this has been inserted and a reasonable propagation time has passed, your DNSSEC aware resolver should be able to query your newly signed zone and the ad bit should be set.
dig smtp.co.za ds
What is not yet included with BIND is the roll-over of KSK – Key Signing Keys. For now, it’s assumed that work will soon be done to rectify this in BIND but its noteworthy to observe that the key for the root has lasted seven years before being renewed.

If you have difficulty finding a COZA Registrar who supports DNSSEC using EPP, you can temporarily (or permanently!) use Posix Systems.

  1. Go to https://vweb.co.za and create an account.

  2. Login and change the default Primary Nameserver to your Nameserver. Use [Submit]
  3. Add the (presumably existing) Domain on to VWEB as a
    “Domain Registration” service, with DNS set to “Reg” Push [Add Now]

  4. This will set up just the Nameservers for this domain. Click on your newly created Domain link and once that has loaded (the Domain page), click on [Domain Registration] to go to the Domain registration page.

  5. Complete the process by pushing the [Check Nameservers] button. This will cross check that your Nameservers are all working.

  6. Transfer the domain to Posix (so Posix can talk to the ZACR). Push the [Transfer] button. You can push [Step 1] (update nameservers). Don’t push [Step 2] (update contacts) yet as it will block any DS record updates. You can do this once the green tick below has been observed.

  7. Once transferred, push the [reread zone info]. This will copy over any KSK’s from your zone,
    place them in their own window on VWEB:

There will also be a CDS entry:

Initially, there will be no green tick but at the first five-minute clock tick, the CDS entry will be put into the CO.ZA zone as a DS record. After COZA reloads the CO.ZA zone (once every fifteen minutes), the Green Tick will appear. Your Domain has been secured.

If left at vweb.co.za, the only charge would be a yearly (currently) R80 (inc VAT) for the Domain renewal. You can transfer the domain elsewhere – but remember – the DS record is in COZA.

The Record can be deleted – which will automatically delete the DS record from CO.ZA – with the same timing criteria as when adding – except the record could be cached for up to one day in Resolving (cache-ing) nameservers.

Manual KSK Key Rollover

If left on vweb and after a suitable time period (a year) you want to roll over the KSK, you’ll need to create a new one by hand, unless there are improvements on the Key Manager.

dnssec-keygen -a rsasha256 -b 2560 -fk smtp.co.za
Notes: -a Algorithm, you might like to also try ECDSAP256SHA256,
-b 2560, The Key Size in bits, discussed previously
-fk - this will generate a KSK type key. Ignore this option for ZSK keys.

Do this in the appropriate key directory. After a day or two (to allow for propagation), login to vweb.co.za, go to the [Domain Registration] page and push the [reread zone info]. This will copy up the new DNSKEY, generate the CDS record and copy the DS record to the Parent.

After two days, remove the old KSK record in the keys directory on your nameserver. After a few hours, login in to vweb and pushing the [reread zone info] should remove the old KSK and CDS records and update the Parent. This is a Key rollover. Remember, you need one fully working chain.


I’m sure that BIND will improve as will the Key Manager. The Key Manager should manage KSK creation and deletion and perhaps even be able to call an external program at the appropriate time. At VWEB, I’ll probably have a URL that when called, will instigate the functionality of the [reread zone info] button.


Years ago, I wrote a script to do all this - basically employing my own Key Manager. The script is available for download from here. It assumes that in the directory /etc/bind/pri/ there will be one directory per zone e.g. /etc/bind/pri/dnssec.co.za/ (so everything to do with one zone is together - including all Keys). Read the file (a Bash Shell script) for more information. The program needs to be run from cron - say once every 5 minutes. This will then (if configured to do so) will sign and keep signed that particular zone file. At one time, it was even clever enough to modify the Key Algorithm for a Zone (e.g. from type 5 to type 8). Might need to re-deploy this to update my Algorithm to type 13 - the Eliptical Curve algorithm.

Mark Elkins - mje(at)posix.co.za - last updated 18th September, 2017