DNSSEC signatures in BIND named

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 guide 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 guide.

1 Introduction

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 (major) versions.

(The developers at ISC take BIND 9 as the starting point, and refer to 9.11 as a 'major version', for example. From version 9.12 all odd-numbered versions are development versions. So far, that is versions 9.13, 9.15, 9.17 and 9.19.)

Where possible and relevant, this guide indicates the (production) version from which the features described are supported. That is important mainly for users of enterprise platforms, who 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 operating system's package management 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 (preferably version 9.16 or higher), 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 guide

DNSSEC functionality was added to BIND over time in a series of feature releases. The added functionality progressed from the generation of key pairs and the signing of zone files, through to automation of the signing process and key management. The following table shows which features were added in which versions.

Table 1: Recommended configurations for the various BIND feature releases.

BIND version

Recommended configuration

9.6

Automation of (re-)signing and key management on basis of scripts and cron jobs, using 'dnssec-keygen' and 'dnssec-signzone'

9.7-9.8

Automated (re-)signing by means of Auto-DNSSEC ('auto-dnssec maintain') Updates by means of Dynamic DNS ('nsupdate -l' and 'rndc sign') Automation of key management on the basis of scripts and cron jobs, using 'dnssec-keygen' and 'dnssec-keygen -S' (smart signing) from version 9.7.2

9.9-9.10

Automated (re-)signing by means of Auto-DNSSEC ('auto-dnssec maintain') in combination with inline signing ('inline-signing yes') Updates by means of 'rndc signing' Automation of key management on the basis of scripts and cron jobs, using 'dnssec-keygen -S' (smart signing)

9.11-9.14

Automated (re-)signing by means of Auto-DNSSEC ('auto-dnssec maintain') in combination with inline signing ('inline-signing yes') Updates by means of 'rndc signing' Automated key management by means of 'dnssec-keymgr' and policy file /etc/dnssec-policy.conf (and a final cron job)

9.15 and above

Automated (re-)signing by means of Auto-DNSSEC ('auto-dnssec maintain') [deprecated in favour of DNSSEC Policy], in combination with inline signing ('inline-signing yes') Updates by means of 'rndc signing' Fully automated key management by means of DNSSEC Policy

The successive versions of BIND provide a natural framework for understanding how the DNSSEC functionality developed. However, this guide covers the BIND version groups in reverse order. We begin with the configuration from versions 15 and 16, then move on to the additions and changes in versions 17 and 18. The main reason for tackling the functionality in this way is that fully automated key management (by means of the DNSSEC Policy) was introduced in version 9.16. As you will see later, the versions that we consider first cover the BIND packages supplied with most current server distributions.

Once we have described DNSSEC configuration in the later versions of BIND, we return to versions 9.11 to 9.14. Although those versions did not support fully automated key management, they took an important step towards it by introducing the 'dnssec-keymgr'command. Version 9.11 is still supplied as the standard DNS package in various current (LTS) server distributions.

In the final part of this guide, we consider DNSSEC as implemented over time in older versions of BIND (9.6 to 9.10). To the best of our knowledge, those versions are not included in any current distributions. However, one does sometimes come across them in older DNS systems and as part of some DNS appliances.

To save users of BIND systems older than version 15 having to wade through information about configuration options that aren't actually available to them, we have endeavoured to make the parts of this guide devoted to versions 9.11 to 9.14 and to versions 9.6 to 9.10 as self-contained as possible. Nevertheless, we hope that the users of older versions will cast an eye over the sections about BIND's more modern functionalities, note how those functionalities simplify DNSSEC configuration, and consider upgrading their DNS systems to version 9.16 or above.

In this guide, we focus consistently on the main functionality and options you need to know about in order to realise a complete (preferably automated) configuration. For the details and information about less everyday options, see the Administrator Reference Manual (ARM) and the BIND man pages.

Contents

Part 1: Basic principles

Part 2: BIND versions 9.15 to 9.18 – Fully automated DNSSEC management

Part 3: BIND versions 9.11 to 9.14 – Automated (re-)signing and key management

Part 4: BIND versions 9.6 to 9.10 – Basic DNSSEC functionality

Part 5: Automated (re-)signing

2 RHEL, CentOS and Fedora

We have used the Red Hat Linux distributions as the basis for this article, because commercially supported, free and multiple community-based variants are available, namely RHEL, CentOS (Stream), Rocky Linux, AlmaLinux and Fedora.

2.1 RHEL and CentOS Stream version 9

RHEL9 includes BIND version 9.16 (version 9.16.23 since the most recent updates to RHEL 9.1). The upstream distribution CentOS Stream 9 is also on version 9.16.23 (as of January 2023).

If you (manually) instal a more recent version of BIND on your existing RHEL9/Rocky9/AlmaLinux9/CentOS9 system, make sure that you install a corresponding new configuration file at the same time.

2.2 RHEL and CentOS (Stream) version 8

RHEL8 included BIND version 9.11 (version 9.11.36 after the final updates to RHEL 8.7). The upstream distribution CentOS Stream 8 is also on version 9.11.36 (as of January 2023).

If you (manually) instal a more recent version of BIND on your existing RHEL8/Rocky8/AlmaLinux8/CentOS8 system, make sure that you install a corresponding new configuration file at the same time. Version 9.16 included important new DNSSEC functionality, which is considered later in this guide.

2.3 Fedora

Fedora 37 includes BIND version 9.18 (version 9.18.7 since the most recent updates), as does the upcoming version Fedora 38 (version 9.18.8 via the updates). Fedora 36 had BIND 9.16 (version 9.16.27 after the final updates).

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 anyone using Ubuntu Server – the most widely used Linux distribution for servers, based on Debian – we have listed the BIND versions supplied with the various releases below.

Table 2: The BIND versions included with the different releases of Ubuntu Server.

Ubuntu Server release

BIND version

14.04.5 LTS (Trusty Tahr) [ESM]

9.9.5

16.04.3 LTS (Xenial Xerus) [ESM]

9.10.3

18.04 LTS (Bionic Beaver)

9.11.3

20.04 LTS (Focal Fossa)

9.16.1

21.10 (Impish Indri)

9.16.15

‍22.04 LTS (Jammy Jellyfish)

9.18.1

‍22.10 (Kinetic Kudu)

9.18.4

‍23.04 (Lunar Lobster)

9.18.4

Part 1: Basic principles

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       192.168.129.36        ; 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       192.168.128.34        ; mail gateway
mx              IN      AAAA    a022:2f87:1098::1:6   ; mail gateway (IPv6)
mail            IN      A       192.168.128.35        ; mail server
mail            IN      AAAA    a022:2f87:1098::1:7   ; mail server (IPv6)

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

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

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

5 DNSSEC in BIND

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.

Table 3: DNSSEC functionality in BIND.

BIND release

Feature

Configuration options and commands

9.7

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

9.9

Inline-Signing

inline-signing yes rndc signing rndc zonestatus (9.10.0)

9.11

key management

dnssec-keymgr /etc/dnssec-policy.conf dnssec-coverage (9.9.3) rndc showzone

9.12

dnssec-cds

9.15-9.16

DNSSEC Policy

dnssec-policy (in zone-configuratie) dnssec-policy keys ksk zsk csk purge-keys publish-safety retire-safety nsec3param signatures-validity signatures-validity-dnskey signatures-refresh zone-max-ttl zone-propagation-delay dnskey-ttl parent-ds-ttl parent-registration-delay parent-propagation-delay parental-agents rndc dnssec -checkds rndc dnssec -status rndc dnssec -rollover

5.1 Cryptographic algorithms

The cryptographic algorithms based on SHA-2 (RSA/SHA-256 and RSA/SHA-512) are available in BIND 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. Finally, the EdDSA-based algorithms (Ed25519 and Ed448) are available from version 9.10.7.

RFC 8624 recommends using algorithm 13 (ECDSA Curve P-256 with SHA-256) alongside algorithm 8 (RSA/SHA-256), which was the standard for a long time but is now slowly being phased out in favour of the ECDSA-based algorithms.

Algorithm 10 (RSA/SHA-512), a variant of number 8, has never gained popularity, and its use is now discouraged. Algorithm 14 (ECDSA Curve P-384 with SHA-384) is a stronger version of number 13, but isn't needed yet. However, it is likely that, in due course, algorithm 13 will be succeeded not by algorithm 14 but by an EdDSA-based algorithm (algorithm 15, Ed25519).

Part 2: BIND versions 9.15 to 9.18 – Fully automated DNSSEC management

The foundations for fully utomated DNSSEC management were introduced to BIND in versions 9.7 to 9.11. First, automatic (re-)signing of zones was introduced in versions 9.7/9.8 ('auto-dnssec maintain'). The functionality was later further incorporated within the code base in versions 9.9/9.10 (Inline-Signing).

From version 9.11, key management was also automated by means of the 'dnssec-keymgr' command and the associated policy file. That meant that the entire DNSSEC set-up was confined to the BIND configuration files, with just 1 final cron job for generating new key pairs (where necessary) using the 'dnssec-keymgr' command.

With the introduction of DNSSEC Policy in version 15/16, BIND's developers took the final step to complete the automation of DNSSEC (signing). From version 9.16, policies for key management and zone signing can be specified in the configuration file named.conf. The software will then automatically ensure that signatures (RRSIG records) and ZSK/KSK pairs are always up-to-date. As a result, scripts and cron jobs are no longer necessary to keep signed zones updated.

6 DNSSEC Policy

From version 9.16 of BIND named, you can specify a 'dnssec-policy' in the 'named.conf' configuration file. That's done by adding a statement to the zone configuration, as follows:

zone "example.nl." {
    type master;
    file "db.example.nl";
    inline-signing yes;
    dnssec-policy "dnssec-policy-1";
};

Note that (from versions 9.16.33 and 9.18.7) the use of DNSSEC Policy requires that you also explicitly state whether you want to use Dynamic DNS (by setting 'allow-update' or 'update-policy') or Inline-Signing. Those 2 alternatives are part of Auto-DNSSEC, which handles the fully automated (re-)signing of your zone using the available key pairs. The first alternative (introduced with version 9.7.0) involves using the Dynamic DNS facility (with the 'local-ddns' key) to sign an existing zone on-the-fly. Inline-Signing (available from version 9.9.0) 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 features are considered in more detail later in this guide.

From version 9.19/9.20, Auto-DNSSEC (deprecated from versions 9.16.36 and 9.18.10) will be withdrawn and completely replaced by DNSSEC Policy (which supports not only fully automated (re-)signing, but also full automated key management).

The DNSSEC policy specified in the zone points to a definition in the global configuration:

dnssec-policy "dnssec-policy-1" {
  ...
  }

So there is no longer a diffuse set of DNSSEC-related configuration options at various locations and in various files. Instead, all aspects of policy are configured and managed at a single central location.

6.1 Key and Signing Policy (KASP)

As well as enabling the automation of re-signing (as Auto-DNSSEC and Inline-Signing did), the Key and Signing Policy (KASP) also allows you to create new key pairs (as you could previously do with the 'dnssec-keymgr'command in combination with a cron job).

The following is an example of a complete policy definition:

dnssec-policy "dnssec-policy-1" {

  keys {
    ksk key-directory lifetime P1Y algorithm 8 4096;
    zsk key-directory lifetime P30D algorithm 8 2048;
    }

  purge-keys P90D;

  publish-safety PT2H;
  retire-safety PT2H;

  nsec3param iterations 0 optout false salt-length 0;

  signatures-validity P14D;
  signatures-validity-dnskey P14D;
  signatures-refresh P5D;

  max-zone-ttl P1D;
  zone-propagation-delay PT5M;

  dnskey-ttl PT1H;

  parent-ds-ttl P1D;
  parent-registration-delay 
  parent-propagation-delay PT1H;

  }

The policy above begins by defining 2 types of key pair: a KSK pair and a ZSK pair based on DNSSEC algorithm 8 (RSA/SHA-256), with key lengths of 4096 and 2048 bits, respectively (the latter is the default, so it wasn't strictly necessary to define it). We have specified a lifespan of 1 year for the KSK pair, and 1 month for the ZSK pair. With algorithm 13 (ECDSA Curve P-256 with SHA-256), there is no need to specify the key length.

The labels 'lifetime' and 'algorithm' don't have to be included in the statements, but we've done so in this example for complete clarity. Key pairs that don't ever need to be rolled over can be labelled 'unlimited'.

If you prefer using only CSK pairs, you can use the label 'csk' (for which you obviously specify only 1 type of key pair).

The following table gives the meanings and default values of the other options available for 'dnssec-policy'.

Table 4: The meaning and default values of the other options available for 'dnssec-policy'.

Option

Meaning

Default value

dnskey-ttl

The TTL of the DNSKEY records created

3,600 seconds (= 1 hour)

‍max-zone-ttl (was only 'zone-max-ttl' in development version 9.15)

The maximum TTL value permitted in the zone, serving to clarify the period within which older RRSIG records should be flushed from caching resolvers when rolling over to a new DNSKEY

24 hours

‍‍nsec3param (available from version 9.16.10)

Settings for NSEC3

NSEC

publish-safety

A safety margin added when publishing a new key pair

1 hour

‍parent-ds-ttl

TTL of the DS records published by the parent zone

1 day (for .nl: 3,600s = 10 hours

‍parent-propagation-delay (from version 9.16.19, the zone configuration option 'parental-agents' is available, allowing a list of servers to be specified to check the DS records in the parent zone)

Time needed for the propagation of changes in the parent zone to all public authoritative name servers

1 hour (for .nl: usually a few seconds; the default value is fine)

‍‍parent-registration-delay (from version 9.16.7, this option has been replaced by the 'rndc dnssec -checkds' command, which can be used to indicate that a new DS record is available in the parent zone)

Time needed to implement changes to the DS records in the parent zone

1 day (for .nl: 1 hour)

‍‍purge-keys (available from version 9.16.13)

Time period after which expired key pairs are deleted

90 days

retire-safety

A safety margin added when disabling a key pair

1 hour

signatures-refresh

The length of time prior to the expiry of a signature (in the RRSIG records) that a new RRSIG record will be generated

5 days

signatures-validity

Duration of the validity of the signatures (in the RRSIG records)

2 weeks

signatures-validity-dnskey

Duration of the validity of the signatures attached to DNSKEY records (containing the public keys)

2 weeks

zone-propagation-delay

Time needed for the propagation of changes from the master to all public authoritative name servers

5 minutes

BIND named includes a default policy (called 'default'), which users (operators) can use as a starting point for defining their own policies.

Note that the syntax for KASP is quite different from the syntax for the policy classes considered later in this guide that are used by the 'dnssec-keymgr' command (defined in the '/etc/dnssec-policy.conf' policy file). Timestamps can be formatted in accordance with ISO 8601 or TTL style.

For details of the timing considerations associated with DNSSEC, see this article, in which we cover them in depth in relation to OpenDNSSEC.

6.2 Key management

From version 9.16.5, the 'rndc dnssec -status' command is available, allowing you to view the current KASP policies, the key pairs currently in use, the status of all key pairs and the rollovers in progress:

[root@system]# rndc dnssec -status example.nl
dnssec-policy: dnssec-policy-1
current time:  Thu Feb 11 16:03:34 2023

key: 43281 (RSASHA512), KSK
  published:      yes - since Fri Aug 28 00:31:44 2022
  key signing:    yes - since Fri Aug 28 00:31:44 2022

  Next rollover scheduled on Wed Feb 10 20:21:50 2023
  - goal:           omnipresent
  - dnskey:         omnipresent
  - ds:             omnipresent
  - key rrsig:      omnipresent

key: 20426 (RSASHA512), ZSK
  published:      yes - since Sat Nov 21 00:31:44 2022
  zone signing:   yes - since Mon Dec 21 00:31:44 2022

  Next rollover scheduled on Sat Mar 20 22:26:44 2023
  - goal:           omnipresent
  - dnskey:         omnipresent
  - zone rrsig:     omnipresent

A rollover can be initiated manually (forced) using the following command (available from version 9.16.8):

rndc dnssec -rollover [-when <datetime>] -key 43281 example.nl

Note that (from version 9.16.7), you need to explicitly give the following command, so that BIND named knows that a new DS record is available in the parent zone. Otherwise, named will not switch to the new KSK pair.

rndc dnssec -checkds -keyid 43281 published example.nl

To tell BIND named that a key pair is no longer available (in the parent zone and in the caches), use this command:

rndc dnssec -checkds -keyid 14385 withdrawn example.nl

From version 9.16.19, you can use the zone configuration option 'parental-agents' (in combination with the 'parent-ds-ttl' option) to specify a complete list of authoritative name servers where DS records should be available. That removes the need to explicitly inform BIND named of each change involving the registration and publication of KSK pairs, since BIND named can use the information provided to decide for itself when it is safe to proceed with the rollover.

6.3 Removing DNSSEC security

If for any reason you want to remove DNSSEC security from a signed zone (without the domain in question being considered "bogus"), the following statement can be used from version 9.16.11. CDS/CDNSKEY records are also published with the DELETE flag set, so that the DS records are automatically deleted from the parent zone (according to the mechanism defined in RFC 8078).

dnssec-policy none

From version 9.16.16, in order to prevent the domain being treated as "bogus", you should start by using the 'insecure' setting until all DNSSEC records have been deleted. After that, you can change the policy setting to 'none' (or omit the 'dnssec-policy' statement altogether).

dnssec-policy insecure

Part 3: BIND versions 9.11 to 9.14 – Automated (re-)signing and key management

7 Automating key management and rollovers

Although the configuration of DNSSEC signing underwent comprehensive change in version 9.15 BIND version 9.11 was actually the first version to support a straightforward means of fully automating both (re-)signing and key management . The new DNSSEC features of version 9.11 clearly showed that the security technology was by that stage mature and that its implementation was nearing completion. Where authoritative name servers are concerned, the most import addition is the 'dnssec-keymgr'command. The command is a Python-based wrapper combining the older 'dnssec-keygen' and 'dnssec-settime' commands to create a single tool for the automation of key management and rollovers.

Automation involves the formulation of an overall policy or zone-specific policies in the '/etc/dnssec-policy.conf' file. 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 Auto-DNSSEC feature mentioned earlier in this guide.

The 'dnssec-keymgr' command will then be something like this:

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

The random generator is specified in the 'dnssec-keymgr' script for use by the 'dnssec-keygen' command (together with the key directory specification). 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).

The 'dnssec-keymgr' command was removed from BIND from version 9.18.0 (because it was made redundant by the introduction of DNSSEC Policy functionality).

7.1 The policy file

The '/etc/dnssec-policy.conf' policy file contains policy classes ('policy <name>'): profiles from which the settings can be inherited by policies or other policy 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;
  };

For the (default) algorithm RSASHA256, the key length is defined in the file above as 2048 bits and 4096 bits for the ZSK pair and the KSK pair, respectively. That overrules the default setting, which is 2048 bits for both types. In addition, 2 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).

7.2 Generating serial key pairs

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

[root@system]# dnssec-keymgr -K /etc/bind/keys/ -r /dev/random
# /usr/sbin/dnssec-settime -K /etc/bind/keys/ -I 20220503135334 -D 20220602135334 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.

7.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 should 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 metadata 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@system]# 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 2023:
    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 2023:
    Publish: example.nl/ECDSAP256SHA256/59790 (ZSK)
    Activate: example.nl/ECDSAP256SHA256/59790 (ZSK)
  Tue Apr 03 13:53:34 UTC 2023:
    Publish: example.nl/ECDSAP256SHA256/12391 (ZSK)
  Thu May 03 13:53:34 UTC 2023:
    Inactive: example.nl/ECDSAP256SHA256/59790 (ZSK)
    Activate: example.nl/ECDSAP256SHA256/12391 (ZSK)
  Sat Jun 02 13:53:34 UTC 2023:
    Delete: example.nl/ECDSAP256SHA256/59790 (ZSK)

No errors found

The 'dnssec-coverage' command was removed from BIND from version 9.18.0 (because it was made redundant by the introduction of DNSSEC Policy functionality).

7.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@system]# rndc zonestatus example.nl
name: example.nl
type: master
files: db.example.nl
serial: 2023012801
signed serial: 2023012803
nodes: 6
last loaded: Sun, 28 Jan 2023 19:54:50 GMT
secure: yes
inline signing: yes
key maintenance: automatic
next key event: Tue, 30 Jan 2023 13:14:01 GMT
next resign node: ns1.example.nl/NSEC
next resign time: Tue, 30 Jan 2023 18:48:44 GMT
dynamic: no
reconfigurable via modzone: no

7.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@system]# 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 2 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 'sig-validity-interval 10 7' option indicates that the digital signatures (the RRSIG records) generated for dynamic DNS zones have a validity period of 10 days. The signatures are then automatically refreshed 7 days before the expiry of the stated period. If you do not specify a refresh value, a default value equal to a quarter of the validity period is used.

The 'dnssec-dnskey-kskonly yes' option is considered later in this guide, in the context of the use of the 'dnssec-signzone' command.

Part 4: BIND versions 9.6 to 9.10 – Basic DNSSEC functionality

8 Generating key pairs and signing the zone file

8.1 Initial configuration

The configuration of DNSSEC in older versions of BIND named begins with the addition of the following 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 generation of DNSSEC-related records on an authoritative DNS server, but also to enable DNSSEC validation on a server that operates exclusively as a resolver.

From as early as version 9.5, 'dnssec-enable yes' is the default setting. From version 9.16.0, the option was redundant, and it was removed altogether in version 9.18.0 and above.

8.2 Generating keys

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

mkdir -p /etc/bind/keys/
chown root:named /etc/bind/keys/
chmod 775 /etc/bind/keys/
cd /etc/bind/keys/

dnssec-keygen -f KSK -3 -a ECDSAP256SHA256 -r /dev/random example.nl

[root@system]# dnssec-keygen -f KSK -3 -a ECDSAP256SHA256 -r /dev/random example.nl
Generating key pair.
Kexample.nl.+013+11769

Prior to version 9.9.2, BIND didn't support ECDSA. In earlier versions, it's therefore necessary to use the options '-a RSASHA256 -b 4096' (RSA/SHA-256 with a key length of 4096 bits). When 1 of the 2 ECDSA algorithms is selected, the key length is specified, removing the need to use the '-b' option.

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

The '-3' option verifies that the selected algorithm is compatible with NSEC3 (as all algorithms from number 6 are). Signed replies can then be returned if a domain name isn't found (NXDOMAIN/NODATA), without it being possible for a malicious actor to 'walk through' and inventory all the addresses within the domain (zone 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.

8.3 ZSK pair

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

[root@system]# dnssec-keygen -3 -a ECDSAP256SHA256 -r /dev/random example.nl
Generating key pair.
Kexample.nl.+013+59790

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.

8.4 Random generator

We have opted to use the pseudo-random generator '/dev/random' to generate the 2 key pairs. 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) generator '/dev/urandom' 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 entropy (randomness).

DSA-based algorithms are particularly susceptible to the effects of a poorly initialised random generator. They are liable to provide insecure key pairs if the generator is not well initialised. 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. BIND can also be combined with an HSM, but that is outside the scope of this article.

8.5 Key files

Generating the 2 key pairs in the manner described results in the creation of 4 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, details of which are given below.

9 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@system]# 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
db.example.nl.signed

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 and the ZSK-ZSK links are excluded. The 'dnssec-dnskey-kskonly yes' zone configuration option has the same effect (and, 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). From version 9.18.0, 'dnssec-dnskey-kskonly yes' is the default configuration.

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 record set, 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 within the relevant range (NXDOMAIN/NODATA) to be reported using a DNSSEC-signed reply.

When the zone file is generated, a check is performed to verify that at least 1 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.

9.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@system]# 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.

9.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 key pairs are currently live:

  • Created

  • Publish: DNSKEY records with a validity period in the past are published.

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

  • Revoke: DNSKEY records with a validity period 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 validity period in the past are published but not (or no longer) used to sign the zone.

  • Delete (previously Unpublish): DNSKEY records with a validity period in the past are neither published nor used to sign the zone.

Using date information, the entire life cycle of a key pair 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.

9.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 of key 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: 20230202134734 (Fri Feb  2 14:47:34 2023)
; Publish: 20230202134734 (Fri Feb  2 14:47:34 2023)
; Activate: 20230202134734 (Fri Feb  2 14:47:34 2023)
; Revoke: 20230205130153 (Mon Feb  5 14:01:53 2023)
example.nl. IN DNSKEY 385 3 13 TlKOgcQK22K3fw8pUC2VZk9P2k1nx5XK8+UIOPU9b/GqwpU6XPqFVh8O qTycyHd/YYg8vzcAtl+K9nBbb621IA==

9.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 3 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. 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 couple of years. With ZSK pairs, rollovers usually take place once a month or once a quarter.

Having just generated the KSK pair and the 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 5 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 5 weeks. In that way, overlapping key pairs are generated so that rollovers can be executed smoothly.

9.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@system]# dig @localhost +dnssec example.nl

; <<>> DiG 9.16.33-RH <<>> @localhost +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

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;example.nl.                    IN      A

;; ANSWER SECTION:
example.nl.             86400   IN      A       192.0.2.36
example.nl.             86400   IN      RRSIG   A 8 2 86400 20230117215936 20221219070640 1396
    example.nl. rabwdZ0NrKUJ3Q9iVjc8zSH+owRTjeWw5ZIiRdwSQs4aBgAcliT/xPCp
    bQfozbtfM/xEZGnAuAApx4XWDaau6RJhzTBnyKkQwnNxocRdqRq+3wv8
    iupU9YQvF+GDVcdMXJYlVMNPjNH3VO6Vq6jvAPVFsDouzc/63z7ZC2kr Yts=

;; AUTHORITY SECTION:
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 20230117033111 20221218130640 1396
    example.nl. ZamHjFmu5Ng3r7TvL2ZMTqCYMKOtUaC6Zk+dhEU710v9VqTKtnXlb8WY
    ga+1gSwFtmtts97Xq3Sy1U1JpfhFTu3eEeU3tLBaZvELuAIEw8Mj4Xh2
    dtOonKUsAiwvWBqE0ZjjiBmXmFoFtVez1SP7vzVUV0ouUT49Up66Nduh Bcs=

;; ADDITIONAL SECTION:
dns1.example.nl.        86400   IN      A       198.51.100.5
dns1.example.nl.        86400   IN      AAAA    2001:db8:cafe::8:5
dns2.example.nl.        86400   IN      A       203.0.113.5
dns2.example.nl.        86400   IN      AAAA    2001:db8:f00d::16:6
dns1.example.nl.        86400   IN      RRSIG   A 8 3 86400 20230122030846 20221223013109 15460
    example.nl. SrFVcwVONHOk97OL81zrdCQw4zZj3bi2/VhZ9edfRydIVGkxv6S8pHgk
    EU72Gp3TFBprHJ7ytM8bNXJ3bi9N0gXKW5oILTCadrHcxL24XQdAdNpO
    uR/XSVQVzbkp9m1HNn7DTQYF2K57JNHXd+Vt/Oh+Nwp/orru1F2pwooh ubM=
dns1.example.nl.        86400   IN      RRSIG   AAAA 8 3 86400 20230122050156 20221222213109 15460
    example.nl. SvpjhSawql1QRtVPzOzGrZ4OtJlRPhPjjYeTei3JGL987zV8AZrTkaFk
    xB0T5ddwiMK7RAkDo0qJm2J49gfJMGQI2lPTmpYdvNUlTI6LieKW1ZDq
    FqjjPrm1fZWOJzvXoEkisD+T+3NLAey6bWJiEB0tYoTfxuudePsIIl+l Y7Y=
dns2.example.nl.        86400   IN      RRSIG   A 8 3 86400 20230121140246 20221222133109 15460
    example.nl. e6p7ktNEw4Vt/DCM6nGYeqTPjxKoKcfx9JJIpoDuC4ph4sS7rFiAniB0
    GpW+DiAua6Ng+CnS1y8mP7WZ+HAlrgGAzdC8fBt5eU90mTbQCjOPmsaB
    a1YAhZs8rWnOER/o6vW1UOwnFw0Sj2Gd0MpTQLIKGGF5OUvP3g9Ve4pC 3+w=
dns2.example.nl.        86400   IN      RRSIG   AAAA 8 3 86400 20230121180325 20221223033109 15460
    example.nl. iZmMeTLSwbv3rD62VAw6rh7Fh3O1RX1woXhOSApAMmvo2VXsP/ClAtIs
    nZA0GdivP6ueMy6aHFak8cZs10c35t0puqp+KycDMOsTjRbKtpnl51b2
    j6yXZkR1yV/+twRvYE8z+BLxxQItSa8LIVlF5e/+/p+pvNv+QdxcKXsW Nlk=

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

9.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's 'dnssec-signzone' and 'dnssec-settime' commands.

In addition, the '-S <key> -i <interval>' options for 'dnssec-keygen' make it very straightforward to automate rollovers (from version 9.7.2). 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).

9.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 metadata. 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 metadata, which is loaded but not published and used to sign the zone, you need to apply the '-G' (Generate) option.

9.8 A single key pair

Another simplification involves not having separate KSK and ZSK pairs, but using a single (KSK) pair, also known as Combined Signing Keys (CSKs).

When the '-z' option is set, '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 'update-check-ksk no' zone configuration option has the same effect (and, 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.

However, regardless of what DNS server software you use, the setup described is generally appropriate 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 parent domain in order to publish and delete DS records.

9.9 DNSSEC records as inclusions

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 when invoking 'dnssec-signzone'.

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 parent 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.

10 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 'dsset-example.nl.' file:

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. From version 9.16.0, the records for SHA-256 (hash algorithm 2) are provided, but those for SHA-1 (hash algorithm 1) are not. And, from version 9.16.24, no records for revoked key pairs are provided any longer..

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

[root@system]# 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 parent domain has therefore been realised. Verification can be based on the key files themselves or the current DNS system:

[root@system]# 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

The 'dnssec-checkds' command was removed from BIND from version 9.18.0 (because it was made redundant by the introduction of DNSSEC Policy functionality).

10.1 Waiting for resolver caches

You can usually upload the key material to the parent 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 parent 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 set.

10.2 CDS and CDNSKEY records

A relatively new automated procedure for registering DNSKEY/DS records with the parent domain is defined in RFC 8078. Once a zone has been signed and linked to a valid chain of trust, new key material can be transferred (in-band) to the parent domain over the DNS(SEC) infrastructure itself.

That involves publishing the zone's current KSK DNSKEY records as CDNSKEY and CDS records as well. The operator of the parent domain regularly scans the authoritative name 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 parent zone as DS records.

Therefore, RFC 8078 provides 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 (complementary).

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 parent domains to request CDS/CDNSKEY records from delegated (sub)zones. The 'dsset-*' files thus generated can be added to the parent 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. From version 9.18.0, the records for SHA-256 (hash algorithm 2) are processed, but those for SHA-1 (hash algorithm 1) are not.

11 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 refreshed where necessary. Signatures derived from a DNSKEY that has since 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 30 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 (
                      20230204101952 20230105101952 59790 example.nl.
                      TqiR14RvCEkCXvNhdnk25Nismk8l2s34fTbd
                      QmCj+1eKvfhZJsS1o6/I/q3F9BNeLWY9Ta7i
                      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 2 weeks (1209600 seconds), 'dnssec-signzone' would be used with the option '-e +1209600'.

11.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 30 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 5: Automated (re-)signing

12 Auto-DNSSEC

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 2 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

12.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 metadata 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 parent domain.

Precise control of the dynamic zone and the signing process is possible by means of the 'nsupdate -l' command. That functionality is significant mainly in relation to definition of the NSEC(3) parameters by injecting an NSEC3PARAM record into the zone information:

nsupdate -l update add example.nl NSEC3PARAM 1 0 0 -

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), with an important update in RFC 9276 (considered in detail here). From BIND version 9.18.0, the settings described above are the default settings.

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 an NSEC3PARAM record to the zone), that possibility is not considered here.

12.2 Set-up

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

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 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 set. That is because signing of the zone information is now an internal process.

12.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 by means of the 'dnssec-loadkeys-interval' configuration option (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, you can set the 'dnssec-secure-to-insecure yes' option in the zone configuration.

The 'auto-dnssec create' option was once reserved for telling BIND named to generate new key pairs to replace keys that are approaching the end of their validity period. 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 the option disappeared from the roadmap. With the arrival of version 9.11, it was replaced by the 'dnssec-keymgr' command (considered in detail in section 7.

12.4 Signed zone files and journal files

With the new set-up, the automatically generated (signed) zone files – in our case the 'db.example.nl.signed' file – 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

13 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 article.

13.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 NSEC3 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 NSEC3 chain is generated as well.

You can check the current status of a zone using the following command:

rndc signing -list example.nl

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

14 Concluding remarks

In this guide, we have considered the DNSSEC support now provided by the most recent versions of BIND (up to and including version 9.18, February 2023), and the support provided by earlier versions. As will be apparent, with version 9.16 and the subsequent versions, it is now relatively straightforward to realise a fully automated DNSSEC installation. Key pair generation, zone file signing, key rollover and key pair management can all run automatically 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 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.

Do you have feedback on the article? Please let us know via communicatie@sidn.nl.