.@ Tony Finch – blog

Here are some notes about using BIND’s new-ish dnssec-policy feature to sign a DNS zone that is currently unsigned.

I am in the process of migrating my DNS zones from BIND’s old auto-dnssec to its new dnssec-policy, and writing a blog post about it. These introductory sections grew big enough to be worth pulling out into a separate article.

This is the first article in a three part series:

what is dnssec-policy?

BIND’s dnssec-policy automates the management of a zone’s DNSSEC keys, as well as keeping the zone signed.

You can put zero or more dnssec-policy blocks at the top level of your named.conf. A dnssec-policy block defines the policy’s name, and contains a fairly simple description of how often DNSSEC keys and signatures should be replaced.

Inside a zone block you can put a dnssec-policy statement that gives the name of the policy that should be applied to the zone. All the DNSSEC gubbins inside the zone will be taken care of by named.

One thing dnssec-policy does not take care of is maintaining the DS records in the parent zone. (It publishes CDS and CDNSKEY records, but not all parent zones pay attention to them.)

what is different

Compared to BIND’s old auto-dnssec, the main change is that DNSSEC keys are now under named’s control. In principle the keys become more like dynamic zone data than static configuration.

There is no longer any need to use the somewhat arcane dnssec-keygen or dnssec-settime commands.

the default policy

There is a predeclared dnssec-policy default that is fairly sensible for most purposes. It specifies:

The default policy is not guaranteed to be stable so you may prefer to declare your own.

signing an unsigned zone

Let’s try dnssec-policy out on a scratch zone.

I’m going to use the default policy, so I don’t need to add any dnssec-policy blocks to my configuration.

In named.conf inside the zone fanf2.ucam.org { … block, I add the line:

    dnssec-policy default;

The zone also needs to have either inline signing:

    # I don't use this
    inline-signing yes;

Or dynamic updates:

    # my zones have this
    update-policy local;

After editing named.conf, I run the command:

    :; rndc reconfig

inspect the logs

In the logs I see some dnssec: info: messages:

    keymgr: DNSKEY fanf2.ucam.org/ECDSAP256SHA256/54827
                (CSK) created for policy default
    Fetching fanf2.ucam.org/ECDSAP256SHA256/54827
                (CSK) from key repository.
    DNSKEY fanf2.ucam.org/ECDSAP256SHA256/54827
                (CSK) is now published
    DNSKEY fanf2.ucam.org/ECDSAP256SHA256/54827
                (CSK) is now active

And because the zone has changed to add the keys and signatures, some follow-up messages:

    notify: info: zone fanf2.ucam.org/IN:
            sending notifies (serial 1715162591)

observe the keys

In named’s working directory (or in my case the key-directory that I configured), there are some new files which need to be backed up in the same way as the zone’s other working files:


query the status

I can get the zone’s DNSSEC status with the rndc dnssec -status command:

    :; rndc dnssec -status fanf2.ucam.org
    dnssec-policy: default
    current time:  Wed May  8 11:04:07 2024

    key: 54827 (ECDSAP256SHA256), CSK
      published:      yes - since Wed May  8 11:03:09 2024
      key signing:    yes - since Wed May  8 11:03:09 2024
      zone signing:   yes - since Wed May  8 11:03:09 2024

      No rollover scheduled
      - goal:           omnipresent
      - dnskey:         rumoured
      - ds:             hidden
      - zone rrsig:     rumoured
      - key rrsig:      rumoured

dnssec-policy states

The dnssec-policy states have somewhat quirky names:

These state names appear in the output of rndc dnssec -status and in the dnssec-policy debug logs.

await state transitions

Now I need to wait for some TTLs to pass, so that the old unsigned records have expired from all caches and everyone can see the signed version of the zone. The dnssec-policy machinery keeps track of the timing for me.

After the “rumoured” states have transitioned to “omnipresent”, I can publish the zone’s DS record to complete the chain of trust. With the default policy’s timing parameters, these state transitions complete after 26 hours.

publish the DS record

To publish the DS record, I cd to my key directory and run the command:

    :; dnssec-dsfromkey Kfanf2.ucam.org.+013+54827

And give its output to the administrators of the parent zone.

(Or not, in this case, since ucam.org isn’t signed. This is why fanf2.ucam.org is a scratch zone!)

After the DS record appears in the parent zone, I can notify the dnssec-policy machinery what has happened:

    :; rndc dnssec -checkds published fanf2.ucam.org

After this point, named knows that the zone’s key is required for the zone’s chain of trust, so the key should be replaced without manual intervention.

logging and timing

By default, dnssec-policy does not log very much. Before setting a dnssec-policy for a zone, increase named’s debug level using rndc trace 3, then it becomes verbosely informative.

These debug logs include details of state transition time constraints, for example:

    time says no to CSK fanf2.ucam.org/ECDSAP256SHA256/54827
            type ZRRSIG state RUMOURED to state OMNIPRESENT
            (wait 90300 seconds)

90300 seconds is 26 hours.

I don’t know another way to get named to emit this timing information.

what’s next

Stay tuned for the next exciting episode, in which our hero will migrate some zones from old and busted auto-dnssec to new hotness dnssec-policy!