Being employed at a large DNSSEC operator it is unthinkable not to run my own authoritve nameserver for with DNSSEC. There several references on the internet on how to run DNS and how DNSSEC works. I assume you can find them yourselve (by looking at the reference section at the bottom of this page).

I use bind 9 as my DNS server.

UDP TCP traffic

On your server you must enable UDP and TCP traffic over port 53 for DNS queries.


Generating the keys is easily done. For speed reasons I used /dev/urandom instead of /dev/random

Generate a Key Signing Key (KSK)

> dnssec-keygen -r/dev/urandom -f KSK -a RSASHA256 -b 1280 
  -n ZONE

Generate a Zone Signing Key (ZSK)

> dnssec-keygen -r/dev/urandom -a RSASHA256 -b 1024 -n 

Finding someone to obey your master

My former colleage Miek Gieben is slaving my zone. Looking for a slave, drop me a message.

Zone signing ceremony

Unforntunately I don't have a sufficticated zone signing ceremony like the root signing ceremony. I simple execute the following command :-(

>  dnssec-signzone -a -N unixtime -e 20151231235959 -o -k <ZSK filename>

-N indicates that I use a serial based on the unix timestamp

-e indicates the date when the zone is no longer valid. I chose to sign my zone once a year.

Testing your local setup

Check your local BIND configuration using the command:

> named-checkconf

Check your local zone configuration:

> named-checkzone /etc/bind/zones/
> named-checkzone /etc/bind/zones/

View the log file /var/log/named/transfer.log to see if a zone has been transfered to your slave server.

And use dig:

> dig @localhost +dnssec +nostats +noedns 
  +noanswer +noadditional

In the anwser look for the "aa" bit.

; <<>> DiG 9.9.5-3ubuntu0.1-Ubuntu <<>> @localhost +dnssec +nostats +noedns +noanswer +noadditional
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42917
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 3, ADDITIONAL: 5

; EDNS: version: 0, flags: do; udp: 4096
;         IN  A

;; AUTHORITY SECTION:      86400   IN  NS      86400   IN  NS      86400   IN  RRSIG   NS 8 2 86400 20151231235959 20150105082241 42384 SYl8wrtqKtYjw9MF7TNonjENtTgmtW9YNPQwfQFcDceTNM1X8dGjQYXc QrWw2CBGY45OxyRca/k8fnH2RrmRGy7X7iIoczarthbTEWoyUEqkoWIr +DpmOjKLFWrF3+0oawYTIPw9Xy7Bn/y4Y9Q5VPvrBXOLa2T3FKQApL/x 1DI=

Creating the chain of trust

To create the chain of trust one must add the DNSSEC key material to the parentzone. Most of the time one can simply add the DS-record but for a .nl domain one must provide the public keymaterial. This is done through the custom interface of the registrar. Allthough this is descibed only short here this is the most essential step as this creates the chain of trust.

For me I added the keytag (6406) the algorithm (RSA-SHA256) the flag (KSK) and the public key itself.

Validating the chain of trust

When validating DNSSEC always keep in mind the TTL. Sometimes it takes a few days to settle down.

The easy way to check if the DNSSEC chain of trust is correct is to execute the following command:

> dig @ +dnssec +nostats +noedns +noanswer

In the result look at the flags section in the last line to see if the "ad bit is set:

; <<>> DiG 9.9.5-3ubuntu0.1-Ubuntu <<>> @ +nostats +noedns
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36218
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

There are other, more comprehensive ways for testing the configuration by using online tester like the one from SIDN or the one from Verisign. These provide more details on your DNSSEC setup

Configuration files


options {
    directory "/var/cache/bind";

    forwarders {

    dnssec-validation auto;

    auth-nxdomain no;    # conform to RFC1035
    listen-on-v6 { any; };

    rate-limit {
          responses-per-second 10; 
          log-only yes;

    statistics-file "/var/log/named/stats.log";

logging {
    category queries{

    channel transfer_log {
        file "/var/log/named/transfer.log" versions 10 size 50m;
        severity info;
        print-time yes;
        print-severity yes;
        print-category yes;

    category xfer-out{


zone "" {
       type master;
       file "/etc/bind/zones/";
       notify yes;
       allow-transfer {


; BIND data file for local loopback interface
$TTL   86400       IN      SOA rik\ (
                              1         ; Serial
                          86400         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;       IN      NS       IN      NS
;       IN      A       IN      AAAA    2a00:f10:121:400:252b:5421:6ba3:3d10
;       IN      MX     10
ns       IN      A 
www      IN      A 
ns       IN      AAAA    2a00:f10:121:400:252b:5421:6ba3:3d10
www      IN      AAAA    2a00:f10:121:400:252b:5421:6ba3:3d10

$include /etc/bind/zones/\<filename\> ; ZSK
$include /etc/bind/zones/\<filename\> ; KSK