DNSSEC Key and Signing Policy
  • 17 Nov 2022
  • 11 Minutes to read
  • Contributors
  • Dark
  • PDF

DNSSEC Key and Signing Policy

  • Dark
  • PDF

BIND 9.16 introduced a new method to maintain DNSSEC on your zones. In addition to the inline-signing and auto-dnssec configuration options, there is now dnssec-policy.

Will eventually replace inline-signingand auto-dnssec

In some future major release, auto-dnssec may be obsoleted by dnssec-policy.

With dnssec-policy, you can specify a Key and Signing Policy (KASP) and group all KASP related configurations together, making your named configuration more intuitive when it comes to DNSSEC and making it easier to enable DNSSEC for your zones. Zones can be secured with DNSSEC as simply as this:

zone "example.com" {
    dnssec-policy "default";

The default policy is a built-in policy. This introduces a single ECDSAP256SHA key and accompanying signatures for the example.com zone. It uses NSEC for denial of existence.

Because this is a built-in policy you don't have to explicitly configure it, but otherwise it would look like this:

dnssec-policy "default" {
    keys {
         csk key-directory lifetime unlimited algorithm ecdsa256;

    // Key timings
    dnskey-ttl PT1H;
    publish-safety PT1H;
    retire-safety PT1H;
    purge-keys P90D;

    // Signature timings
    signatures-refresh P5D;
    signatures-validity P14D;
    signatures-validity-dnskey P14D;
    // Zone parameters
    max-zone-ttl P1D;
    zone-propagation-delay PT5M;
    parent-ds-ttl P1D;
    parent-propagation-delay PT1H;

You can specify your own policy if you prefer a separate KSK and ZSK, a different cryptographic algorithm, or NSEC3. You can also tweak the timings such as signature validity and TTLs.

Rollover correctness is guaranteed by DNSSEC records state machines, BIND 9 tries to follow the timings from the policy, but does not apply them if they would result in the zone becoming bogus.

Below we discuss some migration strategies, as well as how to change your DNSSEC policy.

Turn on DNSSEC

If your zone is currently unsigned, it is now very easy to turn signing on: simply add dnssec-policy default; to your zone configuration. Automatic DNSSEC management requires either the zone to be dynamic (allowing dynamic updates), or inline-signing to be enabled. Then reconfigure named.

It will take some time before it is safe to submit the DS to your parent, to avoid a situation where a resolver fetches the DS but still has a corresponding DNSKEY RRset in the negative cache. When the CDS and CDNSKEY records for the key are published it is safe to submit the DS, see the section on KSK rollover below.

If you have many zones and you want to turn on DNSSEC for all of them with the same policy, you can also set the dnssec-policy option at option or view level.

Multiple zones with the same policy

BIND 9 does not share keys between zones. In other words, if you use the same policy for different zones, a separate set of keys is created for each zone.

BIND 9 as a recursive name server

When running BIND 9 as both a recursive and authoritative name server, it is strongly recommended to set dnssec-policy at the zone level. When setting a dnssec-policy at option or view level, this will also apply to the default built-in empty "arpa" zones.

Migrate to dnssec-policy

If your zone is already signed, hats-off to you! But how do you migrate to the new dnssec-policy? There are a couple of items to take into account.

Wait for rollovers to complete

When you are currently rolling keys, it is not the best time to migrate to dnssec-policy. BIND 9 is able to detect when keys are active or inactive, but it is good practice to not mix the two operational procedures.

Match your existing keys

First, inspect your existing keys. The built-in default policy uses a single ECDSAP256SHA key (combined signing key [CSK], performing both the duties of a KSK and a ZSK, also know as Single Type Signing Scheme); if your zone uses another algorithm or has a separate KSK and ZSK, setting the default policy to your zone immediately starts a rollover because the existing keys do not match the given policy. This is fine if you want to roll over the keys anyway, but if you want to use the same DNSSEC strategy you should first create a dnssec-policy that matches your current situation.

Warning: There is a known issue with migrating Single Type Signing Scheme zones

The legacy key metadata has no information about the role of keys. It determines the role from the key flags: 256 means it is a ZSK, and 257 is converted to a KSK. In other words, migrating a CSK won't work. Versions 9.16.21 and higher will be able to migrate keys in Single Type Signing Scheme zones (that is zones that are signed with just one key) to CSK.

For example, if your zone is now signed with a RSASHA256 2048-bit KSK and a RSASHA256 1024-bit ZSK, you should create the following policy:

dnssec-policy "myway" {
    keys {
        ksk lifetime unlimited algorithm rsasha256 2048;
        zsk lifetime P60D algorithm rsasha256 1024;

zone "example.com" {
    dnssec-policy myway;

In this example the KSK lifetime is set to unlimited, so no KSK rollovers are scheduled. The ZSK lifetime uses an ISO 8601 format to indicate that the ZSK needs to be replaced every 60 days. You can use different values for the key lifetimes; the timing metadata in the existing key files ("; Inactive: ...", "Removed: ...") is adjusted accordingly.

algorithm can take an algorithm number or mnemonic. Specifying the length is optional, but when migrating to dnssec-policy it is better to be explicit, ensuring the policy matches your existing keys.

Note: Private key format must be v1.3

In order to use existing keys for smart signing, the Private-key-format must be set to v1.3. Keys with older versions do not allow metadata and thus are not compatible with dnssec-policy. You can use dnssec-settime -f to migrate your existing keys to the newer format.

Key states

When you reconfigure named to introduce a dnssec-policy that matches your pre-existing keys, their key files are retained so that they continue to be used to maintain your zone's DNSSEC signatures. In addition, named creates the accompanying dnssec-policy state files needed for each key (e.g. Kexample.com.+008+12345.state).

When your existing active keys have been used for a long time, the key states should have been initialized to omnipresent when you restarted named to migrate to dnssec-policy. That means that they have existed in the zone long enough that all resolvers either have these records currently in cache, or they have to refresh them from the authoritative servers. The significant factor is that no resolver would be expected to have a previous instance of this zone's DNSKEY RRset in cache.

If a key has only recently been introduced, the key state will most likely be set to rumoured, meaning that some resolvers may be using it already, whereas others probably haven't seen it yet. When determining key states during a migration, named looks at the key timing metadata and takes into account TTLs and propagation delays to determine if the key has existed in the zone for "long enough" to be given state omnipresent versus rumoured.

Also, inactive keys are migrated; their key states are set to either unretentive (a predecessor key that is being rolled) or hidden (the key has been removed from the zone long enough that no resolver knows about it).

Let's examine a key state file:

; This is the state of key 12345, for example.com.
Algorithm: 8
Length: 2048
Lifetime: 0
KSK: yes
ZSK: no
Generated: 20210818090144 (Wed Aug 18 11:01:44 2021)
Published: 20210818090144 (Wed Aug 18 11:01:44 2021)
Active: 20210818090144 (Wed Aug 18 11:01:44 2021)
PublishCDS: 20210818090144 (Wed Aug 18 11:01:44 2021)
DNSKEYChange: 20210818090149 (Wed Aug 18 11:01:49 2021)
KRRSIGChange: 20210818090149 (Wed Aug 18 11:01:49 2021)
DSChange: 20210818090149 (Wed Aug 18 11:01:49 2021)
DNSKEYState: rumoured
KRRSIGState: rumoured
DSState: rumoured
GoalState: omnipresent

This file contains all the information required to determine the next action with respect to key maintenance. The first five lines determine the role of the key: This key is a 2048 bit RSASHA256 KSK for the zone example.com that has no lifetime set. Next, there are is a bunch of timing information about when this key is expected to be published, when it should start signing, and when the CDS (and CDNSKEY) should be published. We also keep track of when the state machine for various resource records have changed states, and what state they are in (hidden, rumoured, omnipresent, or unretentive).

DSState stuck in rumoured?

If you see the DSState stuck in rumoured after the migration, you need to run rndc dnssec -checkds published example.com to tell BIND that the DS is already published in the parent zone.


You can modify the key state by hand or with dnssec-settime, although this is not recommended unless you know what you are doing. When adding -s to dnssec-settime, the state file also will be modified. In addition to the key timing metadata, you can update the key goal and the key states:

   -g state
          This option sets the goal state for this key. 

   -d state date/offset
          This option sets the DS state for this key.

   -k state date/offset
          This  option  sets  the DNSKEY state for this key.

   -r state date/offset
          This option sets the RRSIG (KSK) state for this key.
   -z state date/offset
          This  option  sets  the RRSIG (ZSK) state for this key.


Are you using NSEC3? Set the nsec3param option:

dnssec-policy "nsec3" {
    nsec3param iterations 1 optout false salt-length 16;

Everything after nsec3param is optional; if you don't specifically set them, BIND 9 uses default values. If you want to make sure that the parameters match your existing NSEC3 parameters, it is better to set those explicitly. Note that you cannot specify a specific salt. But if the existing salt has the same length as salt-length, it matches the policy and no re-salting occurs.

Change your policy

If you decide to change your policy - for example, you want to do an algorithm rollover - it is as simple as editing your policy and reconfiguring named.

Here is an example where we have changed the myway policy to use a single ECDSAP256SHA256 key instead of the RSASHA256 KSK/ZSK split approach. After reconfiguring named, the corresponding zones will introduce a new key and phase out the old keys:

dnssec-policy "myway" {
    keys {
        # ksk lifetime unlimited algorithm rsasha256 2048;
        # zsk lifetime P60D algorithm rsasha256 1024;
        csk lifetime unlimited algorithm ecdsa256;

zone "example.com" {
    dnssec-policy myway;

This policy now is the same as the default policy, so we could have also changed the configuration like this:

zone "example.com" {
    # dnssec-policy myway;
    dnssec-policy default;

Rather than changing the global myway policy, we are attaching a different policy to a single zone. The result is the same for this zone, but allows you to keep some zones using the global (or per-view) myway policy while at the same time migrating one or more other zones to the default.

Key rollover

Key rollovers are done automatically and on a schedule. How often rollovers occur depends on the lifetime of the key. If set to unlimited, no key rollovers will be scheduled; you would need to use rndc dnssec -rollover to start or schedule a manual key rollover.

A note on signing strategies

ZSK rollovers use a Pre-Publish signing strategy; that is, the DNSKEY is prepublished alongside the existing DNSKEY and once propagated, the RRSIGs in the zone are gradually replaced. This happens fully automatically; no additional action from the operator is required.

KSK rollovers use a Double-KSK signing strategy. Just as with ZSK rollovers, the DNSKEY is prepublished next to the existing DNSKEY and after enough time has passed, the DS in the parent may be submitted.

CSK rollovers use a combination of the two signing strategies. The DNSKEY is prepublished and then the zone RRSIGs can be gradually replaced, while at the same time the DS can be submitted.

The ZSK Pre-Publish rollover and KSK Double-KSK are described in more detail in RFC 7583.

Manual key rollover

To perform a rollover independently of any schedule, you can do that using rndc:

rndc dnssec -rollover -key 12345 example.com

This will start a key rollover for key with ID 12345 in zone example.com. You can also schedule a rollover at a specific time by adding -when <datetime> where the datetime is in YYYYMMDDHHMMSS format (UTC). The key lifetime is reduced, and when it is time to introduce the new successor key, BIND automatically does so.

KSK rollover

ZSK rollovers can be fully automated. However, this is not possible for KSK or CSK, because you still need to submit the DS to the parent zone manually before it can be used by resolvers that use DNSSEC validation.

Therefore, it is less usual to give a time-limited key lifetime to a KSK or CSK and more common to instigate a KSK or CSK rollover manually.

The DS for a given key may be submitted if the corresponding CDS and CDNSKEY records have been published.

Lets take the example.com where we replace a key with ID 54321 with its successor - the key with ID 12345. The DS record to submit can be retrieved with dnssec-dsfromkey.

dnssec-dsfromkey -2 Kexample.com+008+12345

named started the key rollover for you, but does not continue through some steps until you signal to BIND that certain important actions have taken place in the parent zone:

  • When you have seen that the new DS RR for your new KSK or CSK has been added to the parent zone, you must signal this fact to BIND in order to continue the rollover.
  • Similarly, you also need to signal to BIND when a KSK or CSK that is being replaced has had its DS removed from the parent zone.

Once the two keys have had their DS records swapped in the parent zone, you can run the following commands:

rndc dnssec -checkds -key 12345 published example.com
rndc dnssec -checkds -key 54321 withdrawn example.com

We have discussed a couple of dnssec-policy migration and update strategies, more information can be found in our DNSSEC Guide.