DNSSEC signatures in BIND named

1 Introduction

Most operators who run their own DNS services use BIND named, the most widely used DNS server software outside the world of the big registrars. BIND named can function as an (authoritative) name server and/or as a (caching) resolver. This article looks at the signing of a zone on an authoritative name server. The configuration of named as a DNSSEC validating resolver is dealt with in a separate article (NL).

BIND's DNSSEC functionality has developed incrementally over the past few years, to become a mature feature of this DNS server software. Because of the incremental development, there are significant differences between successive (minor) versions.

Where possible and relevant, this article indicates the version from which the features described are supported. That is important mainly for users of enterprise platforms, which for stability and security reasons tend not to use the most recent software versions. There will also be cases where an existing BIND software installation has been upgraded by the package management system of the operating system, but the configuration in use is still based on an older version.

We nevertheless recommend using the most recent version of BIND that you can, if for no other reason than that each successive version has bug-fixes and security-fixes absent from the earlier versions.

1.1 How to use this article

This article describes how the DNSSEC functionality of BIND named was added over time in a series of feature releases. From the generation of key pairs and the signing of zone files, through to automation of the signing process and key management. The article's chronological structure enables you to follow the development of the functionality in a natural way. It also means that, if you are implementing DNSSEC in BIND, you don't necessarily have to carry on reading beyond the section dealing with your version's functionality.The main functionality and options offered by each version are discussed, so that you are able to realise a complete (and, where possible, automated) configuration. For the details and information about less everyday options, see the Administrator Reference Manual (ARM) and the BIND man pages.

BIND version Recommended configuration
Automation of (re-)signing and key management on the basis of scripts and cron jobs, using 'dnssec-keygen' and 'dnssec-signzone'
Automated (re-)signing using Auto-DNSSEC ('auto-dnssec maintain'); updates using Dynamic DNS ('nsupdate -l' and 'rndc sign'); automation of key management on the basis of scripts and cron jobs, using 'dnssec-keygen', 'dnssec-keygen -S' (smart signing) from version 9.7.2
Automated (re-)signing using Auto-DNSSEC ('auto-dnssec maintain'), in combination with inline signing ('inline-signing yes'); updates using 'rndc signing'; automation of key management on the basis of scripts and cron jobs, using 'dnssec-keygen -S' (smart signing)
Automated (re-)signing using Auto-DNSSEC ('auto-dnssec maintain'), in combination with inline signing ('inline-signing yes'); updates using 'rndc signing'; automated key management using 'dnssec-keymgr' and policy file /etc/dnssec-policy.conf


Part 1: Generating key pairs and signing the zone file

Part 2: Automation

Part 3: Key management

2 RHEL, CentOS and Fedora

We have used the Red Hat Linux distributions as the basis for this article, since commercially supported, free and community-based variants are available: RHEL, CentOS and Fedora.

2.1 RHEL and CentOS version 7

When RHEL7 (NL) was introduced, it included BIND version 9.9.4. That remains the current version (through the updates of CentOS version 7.4).If you would like to use a more recent version of BIND on a RHEL7/CentOS7 system, you can download the RPM file for version 9.10.3 from Benjamin Kraft's website. If you take that route, make sure that you install a corresponding new configuration file at the same time.

2.2 RHEL and CentOS version 6

RHEL6 originally came with BIND version 9.7.0, but subsequent updates (CentOS version 6.9) upgraded the BIND version to 9.8.2.If you would like to use a more recent version of BIND on an existing RHEL6/CentOS6 system, you can download the RPM files for version 9.10.3 and 9.9.8 from Benjamin Kraft's website. If you take that route, make sure that you install a corresponding new configuration file at the same time. Version 9.9 in particular included important new DNSSEC functionality.

2.3 Fedora

Fedora 26 (and 27) came with BIND version 9.11.1 (updates). Version 9.11 also made new DNSSEC functionality available (NL).With all Linux distributions based on Red Hat (and the RPM package manager), you can look up the current (installed) version of BIND as follows:

rpm -q bind

3 Ubuntu Server

For users of Ubuntu Server, -- the most widely used Linux distribution for servers, based on Debian -- the BIND versions supplied with the various releases are listed in the table below.

Ubuntu Server release BIND version
12.04.5 LTS (Precise Pangolin) 9.8.1
14.04.5 LTS (Trusty Tahr) 9.9.5
16.04.3 LTS (Xenial Xerus) 9.10.3
17.10.1 (Artful Aardvark) 9.10.3
18.04 LTS (Bionic Beaver) 9.11.2

Part 1: Generating key pairs and signing the zone file

4 DNS zone file

The information in this article is based on the assumption that an (authoritative) DNS installation is already in place and functioning properly. In our case, that implies that we have a zone file db.example.nl (download) for the domain example.nl:

$TTL 1d  ; ttl is 1 day
@               IN      SOA     dns1.example.nl. dns.example.nl. (
                                2017101300     ; serial (date & version)
                                8h             ; refresh every 8 hours
                                20m            ; retry after 20 minutes
                                4w             ; expire after 4 weeks
                                20m            ; negative caching ttl is 20 minutes

; DNS name servers
                IN      NS      dns1.example.nl.  ; primary name server
                IN      NS      dns2.example.nl.  ; secondary name server

; SMTP mail gateways
                IN      MX      10 mx.example.nl.            ; MX gateway
                IN      MX      100 fallback-mx.example.nl.  ; fallback MX gateway

; hosts
                IN      A        ; server
                IN      AAAA    a022:2f87:1098::2:14  ; server (IPv6)
www             IN      CNAME   example.nl.           ; WWW server
ftp             IN      CNAME   example.nl.           ; FTP server
mx              IN      A        ; mail gateway
mx              IN      AAAA    a022:2f87:1098::1:6   ; mail gateway (IPv6)
mail            IN      A        ; mail server
mail            IN      AAAA    a022:2f87:1098::1:7   ; mail server (IPv6)

; exterior hosts
dns1            IN      A           ; primary name server
dns1            IN      AAAA    2f87:a022:0941::8:5   ; primary name server (IPv6)
dns2            IN      A          ; secondary name server
dns2            IN      AAAA    2f87:a022:0941::16:6  ; secondary name server (IPv6)
fallback-mx     IN      A         ; fallback mail gateway
fallback-mx     IN      AAAA    0941:20a2:7f34::32:7  ; fallback mail gateway (IPv6)

And that that zone file is configured as the master (primary) in the file /etc/named.conf:

zone "example.nl" {
  type master;
  file "db.example.nl";


Support for DNSSEC was one of the drivers for the development of BIND version 9, particularly where the US military was concerned. Featuring support for NSEC3 and 'automatic zone re-signing', BIND 9.6 was the first version with a modern DNSSEC implementation.

The table below lists the DNSSEC functionality that was added over time in successive feature releases of BIND, as dealt with in this article.

BIND release feature Configuration options and commands
smart signing (9.7.2) dnssec-enable yes dnssec-keygen dnssec-signzone dnssec-dnskey-kskonly yes update-check-ksk no dnssec-settime dnssec-revoke dnssec-verify dnssec-dsfromkey dnssec-checkds
Auto-DNSSEC key-directory "/etc/bind/keys" auto-dnssec maintain update-policy local nsupdate -l rndc sign rndc loadkeys dnssec-loadkeys-interval dnssec-secure-to-insecure serial-update-method sig-validity-interval
Inline-Signing inline-signing yes rndc signing rndc zonestatus (9.10.0)
key management dnssec-keymgr /etc/dnssec-policy.conf dnssec-coverage (9.9.3) rndc showzone

5.1 Cryptographic algorithms

The cryptographic algorithms based on SHA-2 (RSA/SHA-256 and RSA/SHA-512) are available only from version 9.6.2. The ECDSA-based algorithms ('ECDSA Curve P-256 with SHA-256' and 'ECDSA Curve P-384 with SHA-384') are available from version 9.9.2.

We currently consider algorithms 8 (RSA/SHA-256) and 10 (RSA/SHA-512) as a secure minimum. For new DNSSEC deployments, we recommend the more efficient algorithm number 13 (ECDSA Curve P-256 with SHA-256).

Algorithm 1 (RSA/MD5) should certainly no longer be used. We strongly advise against using algorithms based on SHA-1 (still often regarded as standard and used as a default setting). The algorithms in question are number 3 (DSA/SHA1) and 6 (DSA-NSEC3-SHA1), along with numbers 5 (RSA/SHA-1) and 7 (RSASHA1-NSEC3-SHA1).

5.2 Configuration

The configuration of DNSSEC for BIND named begins with the addition of this option to the configuration file:

dnssec-enable yes;

It's important to note that the 'dnssec-enable' option needs to be set to 'yes' not only to enable the provision of DNSSEC-related records by an authoritative DNS server, but also to enable DNSSEC validation by a server used exclusively as a resolver.

5.3 Generating keys

Before we can sign the domain example.nl, we need to generate two key pairs (a KSK and a ZSK pair). The KSK pair is generated using the following commands:

mkdir -p /etc/bind/keys/ cd /etc/bind/keys/ dnssec-keygen -f KSK -3 -a ECDSAP256SHA256 -r /dev/random example.nl [root@services]# dnssec-keygen -f KSK -3 -a ECDSAP256SHA256 -r /dev/random example.nl Generating key pair. Kexample.nl.+013+11769

BIND versions older than 9.9.2 don't support ECDSA. With those versions, we therefore use the options '-a RSASHA256 -b 4096' (RSA/SHA-256 with a key length of 4096 bits). When one of the two ECDSA algorithms is selected, the key length is specified, removing the need to use the '-b' option.

BIND version 9.12 no longer has standard settings for the cryptographic algorithms. The '-a' option is therefore mandatory for 'dnssec-keygen'.

The '-3' option verifies that the selected algorithm is compatible with NSEC3. Signed replies can then be returned if a domain name isn't found (NXDOMAIN), without it being possible for a malicious party to 'walk through' and inventory all the addresses within the domain (name walking).

For DNSSEC key pairs, the 'nametype' and 'class' have to be the same as ZONE and IN, respectively. Because that is in line with the default 'dnssec-keygen' settings, we have omitted the options '-n ZONE -c IN' from the example above. If you want to use a directory other than the current directory for the keys, that can be specified using the '-K' option.

5.4 ZSK pair

We use a similar command to generate the ZSK pair, but without the '-f KSK' option:

[root@services]# dnssec-keygen -3 -a ECDSAP256SHA256 -r /dev/random example.nl
Generating key pair.

For installations older than version 9.9.2, we use the options '-a RSASHA256 -b 2048' (RSA/SHA-256 with a key length of 2048 bits). Because we replace ZSK pairs much more often than KSK pairs (e.g. once a quarter instead of once a year), a key length of 2048 bits is sufficient.

5.5 Random generator

We have opted to use the pseudo-random generator to generate the two key pairs. /dev/random It is a blocking generator and can sometimes be very slow. Speed issues are particularly likely on low-activity machines and very recently started machines, because insufficient random bits are available to seed the generator. Alternatively, therefore, the (non-blocking) /dev/urandom generator may be used. If insufficient random bits are available, the latter generator does not wait for them to become available, but supplies bit strings generated with less seeding entropie (randomness).

DSA-based algorithms are particularly susceptible to the effects of a poorly initialised random generator, leading to insecure key pairs. For a production system, therefore, the '-r /dev/random' option should always be used.

From version 9.12, BIND has by default used a cryptographic library such as OpenSSL to generate random bits.

For both security and scalability reasons, it is best to use a bump-in-the-wire architecture based on OpenDNSSEC and an HSM (hardware security module) for a larger DNS infrastructure. The installation and configuration of OpenDNSSEC is considered in a separate article (NL). BIND can also be combined with an HSM, but that is outside the scope of this article.

5.6 Key files

Generating the two key pairs in the manner described results in the creation of four files in the directory /etc/bind/keys/:

  • Kexample.nl.+013+11769.key

  • Kexample.nl.+013+11769.private

  • Kexample.nl.+013+59790.key

  • Kexample.nl.+013+59790.private

The files with the .private extension contain the private (i.e. secret) keys; their permission is 600. The files with the .key extension contain the public keys in the form of DNSKEY records. The DNSKEY record for the KSK also differs from that for the ZSK, insofar as the values of the flags are, respectively, 257 and 256 (the former has a secure entry point (SEP) flag set). The file names include the relevant domain name, the number of the algorithm used (in this case 13 for ECDSAP256SHA256) and the key ID. The latter is simply a random ('unique') number for distinguishing the various key pairs from one another.

DNSKEY records do not usually have their own TTL values. The TTL of the SOA record is therefore used. However, a TTL can be explicitly set using the '-L' option (from version 9.9.0).

In addition to the key material itself, the files contain date information. The fields are part of the 'smart signing' functionality introduced with BIND version 9.7.0. Further details are provided below.

6 Signing

We use the following command to manually sign the existing zone file db.example.nl:

dnssec-signzone -S -K /etc/bind/keys/ -g -a -r /dev/random -o example.nl db.example.nl
[root@services]# dnssec-signzone -S -K /etc/bind/keys/ -g -a -r /dev/random -o example.nl db.example.nl
Fetching ZSK 59790/ECDSAP256SHA256 from key repository.
Fetching KSK 11769/ECDSAP256SHA256 from key repository.
Verifying the zone using the following algorithms: ECDSAP256SHA256.
Zone fully signed:
Algorithm: ECDSAP256SHA256: KSKs: 1 active, 0 stand-by, 0 revoked
                            ZSKs: 1 active, 0 stand-by, 0 revoked

You may be able to save some space in the signed zone file by including the '-x' option. If that option is activated, only the KSKs are used to sign the DNSKEY RRset. The zone configuration option 'dnssec-dnskey-kskonly yes' has the same effect (from BIND named version 9.10.0 also for slave zones in combination with 'inline-signing'). The latter option is also valid for the CDS and CDNSKEY RRsets (from version 9.12). 

The result is a signed zone file db.example.nl.signed, which includes not only the DNSKEY records, but also an RRSIG record for each resource record set (RRset), containing the digital signature for the RRset in question. In addition, a chain of (signed) NSEC records is added, enabling the non-existence of a queried name (NXDOMAIN) to be reported using a DNSSEC-signed reply.

When the zone file is generated, a check is performed to verify that at least one valid, self-signed KSK is present, and that all the records are signed. The '-a' option ensures that all digital signatures (RRSIG records) are also validated.

6.1 Verification

If you want the whole signed zone file -- including the NSEC chain -- checked, you use the following command:

dnssec-verify -o example.nl db.example.nl.signed
[root@services]# dnssec-verify -o example.nl db.example.nl.signed
Loading zone 'example.nl' from file 'db.example.nl.signed'
Verifying the zone using the following algorithms: ECDSAP256SHA256.
Zone fully signed:
Algorithm: ECDSAP256SHA256: KSKs: 1 active, 0 stand-by, 0 revoked
                            ZSKs: 1 active, 0 stand-by, 0 revoke

If you have a DNSKEY RRset that is signed using only the KSK(s) (as a result of using 'dnssec-signzone' with the '-x' option), the '-x' option needs to be added here as well.

6.2 Smart signing

If the '-S' option (smart signing) is applied, the current public keys (the DNSKEY records as previously generated in the /etc/bind/keys/ directory) are included in the zone file (and signed). The date information in the key files is then used to specify which keys are currently live:

  • Created

  • Publish: DNSKEY records with a date in the past are published

  • Activate: DNSKEY records with a date in the past are published and used to sign the zone

  • Revoke: DNSKEY records with a date in the past are published as revoked (by setting a REVOKE flag); if such a record has a valid Publish date, it is also used to sign the zone

  • Inactive (Retire): DNSKEY records with a date in the past are published but not (or no longer) used to sign the zone

  • Delete (previously Unpublish): DNSKEY records with a date in the past are not published and not used to sign the zone

Using date information, the entire life cycle of a key can be defined.

The date information can be defined when generating the key pairs, by using 'dnssec-signzone' with the '-P/A/R/I/D' options, each followed by a date or offset value. The '-i' option can be used to specify the prepublication interval (the period from publication to activation).

The options can also be applied to existing key pairs using the 'dnssec-settime' command. Bear in mind that 'dnssec-settime' modifies both files (.key and .private) in a key pair.

6.3 Revoke

To set the REVOKE flag on an existing key pair, you can use the 'dnssec-revoke' command. The result is a new set key of files (with a new key ID). If you want to remove the old key files at the same time, add the '-r' option.

; This is a revoked key-signing key, keyid 24625, for example.nl.
; Created: 20180202134734 (Fri Feb  2 14:47:34 2018)
; Publish: 20180202134734 (Fri Feb  2 14:47:34 2018)
; Activate: 20180202134734 (Fri Feb  2 14:47:34 2018)
; Revoke: 20180205130153 (Mon Feb  5 14:01:53 2018)
example.nl. IN DNSKEY 385 3 13 TlKOgcQK22K3fw8pUC2VZk9P2k1nx5XK8+UIOPU9b/GqwpU6XPqFVh8O qTycyHd/YYg8vzcAtl+K9nBbb621IA==

6.4 Key management

If no explicit date options are provided with the 'dnssec-signzone' command, only the Created, Publish and Activate fields are added (all three set to the time of creation, 'now'). In principle, that is also sufficient for DNSSEC, since in protocol-technical terms key pairs have an administrative lifetime, not an absolute lifetime (NL). As can be seen in the signed zone file, the DNSKEY and DS records do not themselves contain timing information (except insofar as they may contain their own TTLs).

In practice, however, key pairs are regularly rolled over. For KSK pairs, the rollover interval is typically a year or a few years. With ZSK pairs, rollovers usually take place once a month or once a quarter.

Having just generated a KSK pair and a ZSK pair, a second ZSK pair can be generated for a rollover by using the following command, for example:

dnssec-keygen -3 -a ECDSAP256SHA256 -P now -A +5w -r /dev/random example.nl

The effect of the options '-P now -A +5w' is that the newly generated key pair is published immediately, but not activated for five weeks. In other words, BIND named immediately adds the associated DNSKEY record to the zone file, but does not use the key pair for signing zone information for a further five weeks. In that way, overlapping keys are generated so that rollovers can be executed smoothly.

6.5 Signed zone

The file db.example.nl.signed that has been generated using 'dnssec-signzone' contains a signed zone that can immediately be loaded by the BIND named server. That involves simply modifying the configuration file /etc/named.conf and reloading it:

zone "example.nl" {
  type master;
  file "db.example.nl.signed";
  #file "db.example.nl";
rndc reconfig
rndc reload example.nl

After that, you can use the following command to check that the DNSSEC records are in fact served by the local DNS server:

dig @localhost +dnssec example.nl
[root@services]# dig @localhost +dnssec example.nl

; <<>> DiG 9.11.1-P3-RedHat-9.11.1-4.P3.fc26 <<>> +dnssec example.nl
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20694
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 4, ADDITIONAL: 11

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

example.nl.             86400   IN      A
example.nl.             86400   IN      RRSIG   A 8 2 86400 20180117215936 20171219070640 1396
    example.nl. rabwdZ0NrKUJ3Q9iVjc8zSH+owRTjeWw5ZIiRdwSQs4aBgAcliT/xPCp
    iupU9YQvF+GDVcdMXJYlVMNPjNH3VO6Vq6jvAPVFsDouzc/63z7ZC2kr Yts=

example.nl.             86400   IN      NS      dns1.example.nl.
example.nl.             86400   IN      NS      dns2.example.nl.
example.nl.             86400   IN      RRSIG   NS 8 2 86400 20180117033111 20171218130640 1396
    example.nl. ZamHjFmu5Ng3r7TvL2ZMTqCYMKOtUaC6Zk+dhEU710v9VqTKtnXlb8WY
    dtOonKUsAiwvWBqE0ZjjiBmXmFoFtVez1SP7vzVUV0ouUT49Up66Nduh Bcs=

dns1.example.nl.        86400   IN      A
dns1.example.nl.        86400   IN      AAAA    2a02:27f8:1098::1:5
dns2.example.nl.        86400   IN      A
dns2.example.nl.        86400   IN      AAAA    2a02:27f8:1098::f:5
dns1.example.nl.        86400   IN      RRSIG   A 8 3 86400 20180122030846 20171223013109 15460
    example.nl. SrFVcwVONHOk97OL81zrdCQw4zZj3bi2/VhZ9edfRydIVGkxv6S8pHgk
    uR/XSVQVzbkp9m1HNn7DTQYF2K57JNHXd+Vt/Oh+Nwp/orru1F2pwooh ubM=
dns1.example.nl.        86400   IN      RRSIG   AAAA 8 3 86400 20180122050156 20171222213109 15460
    example.nl. SvpjhSawql1QRtVPzOzGrZ4OtJlRPhPjjYeTei3JGL987zV8AZrTkaFk
    FqjjPrm1fZWOJzvXoEkisD+T+3NLAey6bWJiEB0tYoTfxuudePsIIl+l Y7Y=
dns2.example.nl.        86400   IN      RRSIG   A 8 3 86400 20180121140246 20171222133109 15460
    example.nl. e6p7ktNEw4Vt/DCM6nGYeqTPjxKoKcfx9JJIpoDuC4ph4sS7rFiAniB0
    a1YAhZs8rWnOER/o6vW1UOwnFw0Sj2Gd0MpTQLIKGGF5OUvP3g9Ve4pC 3+w=
dns2.example.nl.        86400   IN      RRSIG   AAAA 8 3 86400 20180121180325 20171223033109 15460
    example.nl. iZmMeTLSwbv3rD62VAw6rh7Fh3O1RX1woXhOSApAMmvo2VXsP/ClAtIs
    j6yXZkR1yV/+twRvYE8z+BLxxQItSa8LIVlF5e/+/p+pvNv+QdxcKXsW Nlk=

;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Mon Jan 08 12:17:37 CET 2018
;; MSG SIZE  rcvd: 1634

6.6 Automation

Smart signing makes it possible to automate key management and signing, and to interface with management software. That involves writing shell scripts and cron jobs that build on BIND named's 'dnssec-signzone' and 'dnssec-settime' commands.

In addition, the '-S <key> -i <interval>' 'dnssec-keygen' options (from version 9.7.2) make it very straightforward to automate rollovers. Thus, the successor to a particular key pair (a 'linked key') is generated, ready for automatic rollover by means of the 'dnssec-signzone' smart signing mechanism.

The same options are supported by 'dnssec-settime' (e.g. to simplify rolling over to a key pair based on a different cryptographic algorithm) and by 'dnssec-keyfromlabel' (from versions 9.8.8 and 9.9.6).

6.7 No rollovers

If you wish, you can continue using the existing key pairs until they ultimately require replacement for security reasons (e.g. in connection with an incident) or because a new cryptographic protocol is adopted.

If the '-C' option is applied, 'dnssec-keygen' generates 'classic' key files that do not contain any meta-data. That option can be useful if, for example, you want to generate new key pairs for processing by existing management software/scripts. DNSKEY records without date information are always added to the zone file by 'dnssec-signzone' and used for signing.

If you want a key pair that does contain meta-data, which is loaded but not published and used to sign the zone, you need to apply the '-G' (Generate) option.

6.8 A single key pair

Another simplification involves not having separate KSK and ZSK pairs, but using a single (KSK) pair. When the '-z' option is applied, 'dnssec-signzone' uses the KSKs to sign all record sets (as opposed to only the DNSKEY records, including those for the ZSKs, which are used for signing in a stepped KSK/ZSK configuration).

The zone configuration option 'update-check-ksk no' has the same effect (from BIND named version 9.10.0 also for slave zones in combination with 'inline-signing').

The philosophy behind PowerDNS is that the complexity should be hidden from users (operators) as far as possible, and that everything that can be automated should be automated. Where the cryptographic keys are concerned, that implies using a single key pair as standard.

Regardless of what DNS server software you use, it will generally work well only if you rarely or never perform rollovers, or if the process is fully automated. That is because every KSK pair rollover involves multiple interactions with the operator of the superordinate domain in order to publish and delete DS records.

6.9 Using 'Include' to add DNSSEC records

With smart signing, the current public keys are automatically added to the zone file and signed. However, before smart signing was introduced, the DNSKEY records (the .key files) had to be 'manually' added to the zone file before they could be signed using 'dnssec-signzone'. One method of manual addition was to add an $INCLUDE statement to the original zone file. The key pairs to be used for signing were specified at the point of use.It is still possible to get 'dnssec-signzone' to generate a separate file containing the DNSKEY records for the KSKs by applying the '-C' option. That can be useful mainly where key material needs to be delivered to the operator of the superordinate domain -- the final step in signing a domain.If you want all DNSSEC-specific records -- DNSKEY, RRSIG, NSEC(3) and NSEC3PARAM -- kept separate from the zone file, you need to apply the '-D' option when using 'dnssec-signzone'. The resulting file, db.example.nl.signed, can then be added to the existing zone file by using an $INCLUDE statement.

7 Uploading key material

SIDN, the operator of the .nl top-level domain, asks its registrars to provide DNSKEY records, rather than DS records, in order to realise the DNSSEC link (part of the chain of trust). By generating DS records from the DNSKEY records, SIDN retains control over the hash-algorithm that is used.

The DS records (for both algorithm 1 and algorithm 2) are generated at the same time as the signed zone file and placed in the file dsset-example.nl:

example.nl.    IN DS 11769 13 1 390B0855277C304F9D32FD8A81F6122828DACBC1
example.nl.    IN DS 11769 13 2 57B09F079CFB3B7767B6B8EA03A70FFB861469565CB2CA07961C3169 0837B9B7

The registries for most other top-level domains ask registrants for the latter record (digest type number 2, a digital extract in accordance with SHA-256).If necessary, you can generate the DS records from a (public) key file using the 'dnssec-dsfromkey' command:

dnssec-dsfromkey Kexample.nl.+013+11769.key

[root@services]# dnssec-dsfromkey Kexample.nl.+013+11769.key example.nl. IN DS 11769 13 1 390B0855277C304F9D32FD8A81F6122828DACBC1 example.nl. IN DS 11769 13 2 57B09F079CFB3B7767B6B8EA03A70FFB861469565CB2CA07961C31690837B9B7

You can use the Python-based 'dnssec-checkds' command to verify that a registered DS record does in fact belong to a particular DNSKEY record, and that the link to the superordinate domain has therefore been realised. Verification can be based on the key files themselves or the current DNS system:

[root@services]# dnssec-checkds example.nl
DS for KSK example.nl/013/11769 (SHA-1) missing from parent
DS for KSK example.nl/013/11769 (SHA-256) found in parent

7.1 Waiting for resolver caches

You can usually upload the key material to the superordinate domain's operator using the registrar's management console. Although it is tempting to do so immediately after signing a domain, it is important to wait until the new (signed) zone is universally available, i.e. until the old zone information has been deleted from all resolver caches. The lifetime of the caches is determined by the TTL value. As long as a validating resolver is still working on the basis of the old zone information, it will block domain names that it is expecting to be signed in accordance with the information in the superordinate zone.The operators of delegated (sub)domains can get DS records from the dsset-* and keyset-* files added to the signed zone file by using 'dnssec-signzone' with the '-g -d <directory>' options applied.

7.2 CDS and CDNSKEY records

A relatively new automated procedure for registering DNSKEY/DS records with the superordinate domain (NL) is defined in RFC 7344 and 8078. Once a zone has been signed and linked to a valid chain of trust, new key material can be transferred to the superordinate domain using the DNS(SEC) infrastructure itself (in-band).That involves publishing the zone's current KSK DNSKEY records as CDNSKEY and CDS records as well. The operator of the superordinate domain regularly scans the authoritative servers for the delegated (sub)domains for new CDNSKEY/CDS records. The digital signature appended to the records guarantees their authenticity, enabling them to be securely published in the superordinate zone as DS records.Therefore, RFC 7344 and 8078 provide a mechanism for the exchange of key material between parent and child zones, similar to that provided for in RFC 5011, but operating in the opposite direction.To make use of the mechanism, you need to add the options '-P sync' and '-D sync' (plus date/offset specification) to your 'dnssec-signzone' and 'dnssec-settime' commands when publishing and deleting the CDNSKEY/CDS records. From BIND version 9.12, the records are also incorporated by the smart signing function.BIND version 9.12 introduced the 'dnssec-cds' command, which enables operators of superordinate domains to request CDS/CDNSKEY records from delegated (sub)zones. The dsset-* files thus generated can be added to the superordinate zone using the 'dnssec-signzone' command with the '-g -d <directory>' options. With 'dnssec-cds', you also have the ability to generate a series of 'nsupdate' commands for use with dynamic zones.

8 Re-signing

The configuration described above yields a static set-up that can easily be maintained using cron jobs. If you use a previously signed zone file as input for 'dnssec-signzone', the signatures will be updated where necessary. Signatures derived from a DNSKEY that has already been deleted remain present as long as they are still valid. That enables continued use of DNSKEY RRsets retained in the caches of validating resolvers.By default, the RRSIG records in the signed zone file are assigned a validity period of thirty days from the date of signing. You can see that in the file itself: each RRSIG record includes its start time and end time in absolute form, e.g.:

    86400    RRSIG    SOA 13 2 86400 (
                      20180204101952 20180105101952 59790 example.nl.
                      wq2qx7T8sE8RvA== )

Note that, in the record itself, the first date is the end date and the second is the start date.Non-default start and end times can be set by using the '-s' option and '-e' option, respectively. A start or end time can be specified either in absolute form or in relative form. So, for example, for a validity period of two weeks (1209600 seconds), 'dnssec-signzone' would be used with the option '-e +1209600'.

8.1 Refresh

Related functionality is provided by the '-i' option, which can be used to specify a refresh interval (in seconds). If you use 'dnssec-signzone' with a previously signed zone file as input, only those records whose validity is due to expire within the refresh interval are re-signed. Hence, the interval works as a security period for re-signing.If no refresh interval is specified, a value equal to a quarter of the total validity duration of the signatures is used. Therefore, if the default validity period of thirty days is effective, the default refresh interval is 7.5 days.In that case, a daily cron job is sufficient to keep the signed zone file up to date.Where a large zone is concerned, it is advisable to add the '-j' option to the 'dnssec-signzone' command as well. Then the validity period of the individual signatures is increased by an additional (randomly defined) period, so that their end dates diverge over time. That in turn means that the signatures require refreshing at different times and the hardware resource requirement of each refresh operation is reduced.

Part 2: Automation


From version 9.7.0, BIND named supports the 'auto-dnssec' zone configuration option. That involves internal use of BIND named's Dynamic DNS facility (with the 'local-ddns' key) to sign an existing zone on-the-fly. The process described above can therefore be automated, doing away with a lot of the drudgery involved in manual re-signing and key management.Auto-DNSSEC supports two distinct levels of automation. If the option 'auto-dnssec allow' is activated, you simply have to generate (or place) the key pairs in the key directory before getting the zone (re-)signed using this command:

rndc sign example.nl

However, in this mode, the 'rndc sign' command will have to be used each time a key pair is rolled over or the signatures are nearing the end of their validity period.If you simply want to refresh the DNSKEY records in a zone in line with changes to the key directory, without simultaneously changing all the digital signatures, use the following command (available from BIND version 9.7.2):

rndc loadkeys example.nl

9.1 Maintain

If you use the 'auto-dnssec maintain' option, the key directory is checked every hour for changes to the key pairs. Depending on the meta-data in the key files, each key pair is assigned the status 'unpublished', 'published', 'active', 'expired' or 'withdrawn'. Thus, the published DNSKEY records are automatically kept up to date. In addition, the digital signatures (in the RRSIG records) can be reset where necessary. The effect of this option is therefore the same as the effect of including the 'rndc sign' command in a cron job, in combination with the 'auto-dnssec allow' option.With auto-DNSSEC, it is very easy to automate the rollover of ZSK pairs, simply by periodically putting the new keys in the key directory (using the 'dnssec-keygen -S <key> -i <interval>' command). BIND named will automatically publish the new keys as DNSKEY records, and start using them for signing as soon as they become active. In principle, the process is the same for KSK pairs, except insofar as the associated key material has to be 'manually' registered with the superordinate domain.Precise control of the dynamic zone and the signing process is possible using the 'nsupdate -l' command. That functionality is significant mainly in relation to definition of the NSEC(3) parameters by injecting a NSEC3PARAM record into the zone information:

nsupdate -l update add example.nl NSEC3PARAM 1 1 100 1234567890

That procedure is followed because the default settings stipulate the use of NSEC, rather than the newer NSEC3.The (re-)signing process begins as soon as the command is sent, and the NSEC(3) chain is generated as well.The contents of the NSEC3PARAM record type are defined in RFC 5155 (section 4).Although the whole process of (re-)signing a zone can be directly controlled using nsupdate without the need for auto-DNSSEC (by successively adding the DNSKEY records and a NSEC3PARAM record to the zone), that possibility is not considered here.

9.2 Setup

In order to make use of auto-DNSSEC, the following option is added to the configuration file /etc/named.conf:

key-directory "/etc/bind/keys"

Also, the 'auto-dnssec maintain' and 'update-policy local' options are added to each individual zone configuration:

zone "example.nl" {
  type master;
  file "db.example.nl";
  auto-dnssec maintain;
  update-policy local;

The following command is then entered, so that BIND named loads the new configuration:

rndc reconfig

Whereas previously the name of the zone file 'db.example.nl' was replaced in the configuration file by the signed zone file 'db.example.nl.signed' generated using 'dnssec-signzone', the name of the original zone file is retained when the 'auto-dnssec' option is used. That is because signing of the zone information is an internal process.

9.3 Signing

When loading a zone file for the first time, with the DNSSEC keys already present, the file is signed automatically and no 'rndc sign' command is required.If the default frequency set for the 'auto-dnssec maintain' function (hourly) is inappropriate, you can adjust it using the configuration option 'dnssec-loadkeys-interval' (from BIND named version 9.10.0 also for slave zones in combination with 'inline-signing').If you want to undo the signing of a zone, place the option 'dnssec-secure-to-insecure yes' in the zone configuration.The option 'auto-dnssec create' was once reserved for telling BIND named to generate new key pairs to replace expired keys. That should have completed the automation of DNSSEC. However, the developers subsequently decided that the relevant functionality wasn't appropriate for inclusion in named, so it was removed from the roadmap. With the arrival of version 9.11, it was replaced by the 'dnssec-keymgr' command (considered later in this article).

9.4 Signed zone files and journal files

With the new set-up, the automatically generated (signed) zone files -- in our case the file db.example.nl.signed -- are no longer in a directly readable form. In the interest of speed, zone files are now saved in a binary format (raw). If you do want to read them, use the following command:

named-checkzone -D -f raw -o - example.nl db.example.nl.signed

Otherwise dig:

dig @localhost axfr example.nl

In addition, a journal file -- db.example.nl.jnl in our case -- is maintained for each dynamic zone. Journal files are also in a binary format. They can be viewed using the following command:

named-journalprint db.example.nl.jnl

10 Inline-Signing

From version 9.9.0 BIND also supports Inline-Signing. The inline signing function is a further development of auto-DNSSEC in combination with the 'update-policy local' option and no longer makes (inappropriate) use of dynamic DNS. The introduction of inline signing means that DNSSEC is also easy to set up on DNS servers that need to be static (e.g. because they receive their zone files from a database-driven back-end or some other type of DNS software).A typical set-up has a (hidden) master server that does the inline signing and then distributes the signed zone file to a number of (public) slave servers. Another possibility is to add a BIND named server to the DNS infrastructure as a bump-in-the-wire, and configure it for inline signing. However, a set-up of that kind could also be realised using OpenDNSSEC, which is specifically intended for that purpose. The configuration of OpenDNSSEC is considered in a separate other article (NL).

10.1 Configuration and use

The configuration of a zone for Inline-Signing is almost exactly the same as configuring for auto-DNSSEC on the basis of dynamic DNS:

zone "example.nl" {
  type master;
  file "db.example.nl";
  auto-dnssec maintain;
  inline-signing yes;
  #update-policy local;

The actual use of an inline signing installation is also as described above. The 'rndc signing' command is now available for the control initially exercised using the 'nsupdate -l' command. However, it is important to be aware of the difference between the 'rndc signing' command and the older 'rndc sign' command.The NSEC(3) parameters are now set using the 'rndc signing -nsec3param' command. That generates the NSEC3PARAM record that was previously injected into the zone information using an 'nsupdate -l' command. The (re-)signing process begins as soon as the 'rndc signing -nsec3param' command is sent, and the NSEC(3) chain is generated as well.You can check the current status of a zone using the following command:

rndc signing -list example.nl
[root@services]# rndc signing -list example.nl
Done signing with key 8160/RSASHA256
Done signing with key 19273/RSASHA256

Part 3: Key management

11 Further automation

From the new DNSSEC features of BIND version 9.11 (NL) it is clear that this security technology is now mature and the implementation is nearing completion. The main addition of relevance in connection with authoritative name servers is the 'dnssec-keymgr' command. As suggested above, this Python-based wrapper combines the 'dnssec-keygen' and 'dnssec-settime' commands to form a tool for the automation of key management and rollovers.Automation involves the formulation of an overall policy or zone-specific policies in the file /etc/dnssec-policy.conf. The contents of that file are then used by 'dnssec-keymgr' (e.g. in the context of an hourly cron job) to generate new key pairs where required. After that, the new keys are automatically adopted using the previously described Auto-DNSSEC feature.The 'dnssec-keymgr' command will then be something like this:

dnssec-keymgr -K /etc/bind/keys/ -r /dev/random

The random generator and the key directory are specified in the 'dnssec-keymgr' script for use with the 'dnssec-keygen' command. Where appropriate, an alternative path can be specified for the configuration file using the '-c' option. The key directory can also be specified in the policy file itself (e.g. for each zone).

11.1 Policy file

The policy file '/etc/dnssec-policy.conf' contains policy classes ('policy <name>'): profiles from which the settings can be inherited by policies of other classes. An algorithm policy ('algorithm-policy <algorithm>') contains settings for an individual cryptographic algorithm. Finally, a zone policy ('zone <name>') contains the policy for a particular zone.The following is an example of a policy's contents:

  algorithm-policy RSASHA256 {
    key-size zsk 2048;
    key-size ksk 4096;

  policy normal {
    algorithm RSASHA256;
    roll-period zsk 3mo;
    roll-period ksk 1y;
    pre-publish zsk 1mo;
    pre-publish ksk 1mo;
    post-publish zsk 1mo;
    post-publish ksk 1mo;
    coverage 6mo;

  policy extra {
    algorithm RSASHA256;
    roll-period zsk 6mo;
    roll-period ksk 2y;
    pre-publish zsk 1mo;
    pre-publish ksk 1mo;
    post-publish zsk 1mo;
    post-publish ksk 1mo;
    coverage 1y;

  zone example.nl. {
    policy normal;
    algorithm ECDSAP256SHA256;

In the file above, the length of the (default) algorithm RSASHA256 is defined as 2048 bits for the ZSK pair and and 4096 bits for the KSK pair. That overrules the default setting, which is 2048 bits for both types. In addition, two policies are defined: 'normal' and 'extra' (the latter featuring longer time intervals). Finally, the 'normal' policy is used for the zone example.nl, but then in combination with the ECDSAP256SHA256 algorithm (number 13).

11.2 Generating serial key pairs

The following example illustrates how 'dnssec-keymgr' builds on the previously generated key files in the /etc/bind/keys/ directory in order to comply with the policy defined for example.nl:

[root@services]# dnssec-keymgr -K /etc/bind/keys/ -r /dev/random
# /usr/sbin/dnssec-settime -K /etc/bind/keys/ -I 20180503135334 -D 20180602135334 Kexample.nl.+013+59790
# /usr/sbin/dnssec-keygen -q -K /etc/bind/keys/ -S Kexample.nl.+013+59790 -r /dev/random -i 2592000

First, the timing information in the existing ZSK files (with key ID 59790) is modified. Then a corresponding key pair is generated.

11.3 Coverage

The 'dnssec-coverage' command (also based on Python and available in BIND from version 9.9.3) can be used to check the remaining validity period of a zone's existing and serial/overlapping key pairs collectively. The check enables you to verify that the zone's signed status will not be interrupted (rendering your domain names unreachable for validating resolver users).

dnssec-coverage -K /etc/bind/keys/ -m 1d -d 1d -r 1w example.nl

When you use the 'dnssec-coverage' command, not only is the meta-data in the key files consulted, but information is also required regarding the maximum TTL (using the '-m' option), the TTL for the DNSKEY records (using the '-d' option) and the period until re-signing (using the '-r' option). If you load the zone data from a file (using the '-f' option), 'dnssec-coverage' will use the TTL information from the zone file itself.When no zone name is specified, 'dnssec-coverage' will return details of all the zones in the key directory. With the '-l' option applied, the response will detail only those zones that require attention within a given period. Finally, there are the '-z' and '-k' options, which limit the check to, respectively, ZSK pairs only and KSK pairs only.The following example illustrates use of the command to check the coverage of the key files that we generated earlier for the domain example.nl:

[root@services]# dnssec-coverage -K /etc/bind/keys/ -m 1d -d 1d -r 1w example.nl
PHASE 1--Loading keys to check for internal timing problems
PHASE 2--Scanning future key events for coverage failures
Checking scheduled KSK events for zone example.nl, algorithm ECDSAP256SHA256...
  Fri Feb 02 13:47:34 UTC 2018:
    Publish: example.nl/ECDSAP256SHA256/24497 (KSK)
    Activate: example.nl/ECDSAP256SHA256/24497 (KSK)

No errors found

Checking scheduled ZSK events for zone example.nl, algorithm ECDSAP256SHA256...
  Fri Feb 02 13:53:34 UTC 2018:
    Publish: example.nl/ECDSAP256SHA256/59790 (ZSK)
    Activate: example.nl/ECDSAP256SHA256/59790 (ZSK)
  Tue Apr 03 13:53:34 UTC 2018:
    Publish: example.nl/ECDSAP256SHA256/12391 (ZSK)
  Thu May 03 13:53:34 UTC 2018:
    Inactive: example.nl/ECDSAP256SHA256/59790 (ZSK)
    Activate: example.nl/ECDSAP256SHA256/12391 (ZSK)
  Sat Jun 02 13:53:34 UTC 2018:
    Delete: example.nl/ECDSAP256SHA256/59790 (ZSK)

No errors found

11.4 Zone status

In addition, from BIND version 9.10.0, you can use the 'rndc zonestatus' command to obtain a detailed statement of the status of a particular zone:

[root@services]# rndc zonestatus example.nl
name: example.nl
type: master
files: db.example.nl
serial: 2018012801
signed serial: 2018012803
nodes: 6
last loaded: Sun, 28 Jan 2018 19:54:50 GMT
secure: yes
inline signing: yes
key maintenance: automatic
next key event: Tue, 30 Jan 2018 13:14:01 GMT
next resign node: ns1.example.nl/NSEC
next resign time: Tue, 30 Jan 2018 18:48:44 GMT
dynamic: no
reconfigurable via modzone: no

11.5 Show zone

A related command is 'rndc showzone' (available from BIND version 9.11.0), which retrieves the current configuration settings for a given zone:

[root@services]# rndc showzone example.nl
zone "example.nl" in { type master; file "db.example.nl";
auto-dnssec maintain; dnssec-dnskey-kskonly yes;
inline-signing yes; key-directory "/etc/bind/keys";
serial-update-method date; sig-validity-interval 10 7; };

The latter example features two further configuration options not previously considered. When the (default) option 'serial-update-method date' is applied, the serial number of a dynamic DNS zone is increased by 1 every time that a change is made. The alternative to the default setting is 'serial-update-method unixtime', which causes the number of seconds since the UNIX epoch to be inserted instead of the serial number (unless the current serial number is equal to or greater than the number of seconds).The option 'sig-validity-interval 10 7' indicates that the digital signatures (the RRSIG records) generated for dynamic DNS zones have a validity period of ten days, and that they are automatically refreshed seven days before that period expires. If you do not specify a refresh value, a default value equal to a quarter of the validity period is used.The option 'dnssec-dnskey-kskonly yes' was considered earlier in the context of the use of the'dnssec-signzone' command.

12 Concluding remarks

That brings us to DNSSEC as now supported by the latest versions of BIND. As will be apparent, with version 9.11 it is relatively straightforward to realise an almost fully automated DNSSEC installation. Key pair generation, zone file signing, key rollover and key management can all run independently following the initial configuration. Generally speaking, only the uploading of KSK material after a KSK rollover has to be done manually. However, that procedure too will cease to require human intervention once RFC 7344 and 8078 (the CDN/CDNSKEY records) have been generally implemented.If and when new DNSSEC functionality is added to BIND, we will update this article accordingly.


  • Friday 20 April 2018


    Got lots of domain names? Here's how to keep track!


    Easy portfolio management

    Read more
  • Monday 18 February 2019

    SIDN Labs

    .nl not affected by global domain hijacking campaign


    We will be further extending our DNS monitoring facilities

    Read more
  • Wednesday 21 March 2018


    Webinar about the implications of the GDPR for domain name registration


    5 April 2018, 15:30 to 17:00 (CEST)

    Read more


Your browser is too old to optimally experience this website. Upgrade your browser to improve your experience.