DNS » History » Revision 22

« Previous | Revision 22/24 (diff) | Next »
Marc Dequènes, 2020-05-02 08:05


Zone Management

Adding a Zone

On each DNS server, master zone can be created/updated on /etc/bind/masters/. The ownership needs to be:
  • banya: if a user zone which should be updatable via the Banya service
  • root:bind in all other cases

The zone is declared in host_vars/<dnsserver>/dns.yml and the playbook playbooks/tenants/duckcorp/dns.yml is in charge of updating all configurations. Only the zone content is not Ansible managed.

Updating a Zone

Edit the file /etc/bind/masters/<zone-name>.zone on the primary master (Orfeo for all zones except DuckLand zones using Elwing).

Do not forget to update the serial!

Better to check the file validity before publishing the zone:

named-checkzone <zone-name> <zone-file>

Then to publish the zone (DNSSEC-signed zones too):

rndc reload <zone-name>

In case the zone is DNSSEC-signed, the publishing of keys in the parent zone is to be done manually (not automated yet); more details below.

Reseting the Zone Serial

The serial needs to be increased by steps, as described in this article.

Secure Zone Transfers

To secure zone transfers, a TSIG key needs to be created and added on both sides. Beware the key name must be identical on both side.

DNS server groups (servers allowed to request transfer) and keys can be defined in host_vars/<dnsserver>/dns.yml and host_vars/<dnsserver>/dns.vault.yml respectively. If they are to be used on all servers, then you can declare them in group_vars/dns_servers/dns.yml and group_vars/dns_servers/dns.vault.yml respectively.

You can a new key using:

dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST taiste

Take the 'Key' part in 'Ktaiste.*.private' file, to put into the configuration.

The same playbook (playbooks/tenants/duckcorp/dns.yml) is used to update the configuration.


Here are notes about using Bind inline-signing and key management. Important fixes for inline-signing are expected in version 9.13 (so 9.14 stable), and hopefully more DNSSEC tooling improvements (like full KSK rollover scheduling).

All general info above about DNSSEC does not change, expecially the rollover steps are similar even if the tooling change, and testing the zone is identical.

The Ansible bind role has been updated in a branch to be able to use Bind directly for DNSSEC. Our Ansible repository now tracks this branch (which still supports OpenDNSSEC) and add the necessary parameters to use it. Please look at the role's documentation to understand the inner technical details, this page is about administration of the solution.


Better read some documentation before fiddling with the controls:

Key materials are initially created by the role when a zone is declared in Ansible, so no need to do anything outside Ansible. Cleanup when a zone is removed is not yet done though. As Bind is not using the usual date-based zone serial, it can be less misleading to reset the serial (see dedicated chapter above).

Zone Status

General zone info, including the real published serial (after signing, resigning if it happens, rollovers…) and planned signing events:

rndc zonestatus <zone-name>

Zone Keys

To know which keys (<key-id>) are currently signing a zone (may be inactive and not deleted yet):

dig +noall +answer +multi <zone-name> DNSKEY | grep KSK
(rndc signing -list <zone-name> cannot be used because of a bug)

There is no way yet to know which is the KSK or ZSK without looking at the key materials. Keys are stored in /etc/bind/keys and you can use the key ID to locate the corresponding file this way:

ls /etc/bind/keys/K<zone-name>.+*+*<key-id>.key

Inside you can read the key type (KSK/ZSK) and the lifetime schedule (so important rollover dates).

dnssec-keymgr is in charge of the key maintenance according to the policy. It is possible to alter the timing using the dnssec-settime tool, for example to schedule an emergency rollover if a key is compromised.
In this case, after doing the modifications, Bind needs to be notififed using:

rndc loadkeys <zone-name>

Parent Zone Publishing

To see if the zone KSK keys are properly published in the parent zone:

dnssec-checkds <zone-name>

(SHA-1 is obsolete, so not published)

Key Rollover

The ZSK key rollover is handled automatically by Bind (dnssec-keymgr in crontab), so admins have nothing to do.

The KSK rollover implies contact with the parent zone and a manual step to get the DS entry in their zone is needed. Creating the new keys and planning the change is also done automatically using the same tool.

To get a view of the schedule (past events for currently involved keys are displayed too) (beware it is using UTC):

dnssec-coverage -K /etc/bind/keys -m 1w -d 1d -k

To have a list of KSK keys that needs publishing on the parent zone:

dnssec-checkds <zone-name>

KSK Rollover Workflow

We use the Double-Signature method with some overlap of DS publishing.

Here are the states and what needs to be done:
  • created state:
    • new created key (new zone or key replacement), this key is not used yet
    • action: wait
  • publish state:
    • the is added to the zone but not used to sign yet
    • after the zone default TTL has passed, it is considered published
    • action: wait for propagation
  • active state:
    • the key is used for signing
    • action: export the key either (depending on the registrar):
      • DS: in digest format using the dnssec-dsfromkey -2 <ksk-filename> command (see previous chapter to get the absolute filename for the current KSK key, any of the key or private file would do)
      • full key: in <ksk-filename> the <key> is on a line formated like <zone-name> <ttl> IN DNSKEY <flags> <protocol> <algorithm> <key> (<flags>, <protocol> and <algorithm> are three numbers, the rest is the <key>; you can copy it with the spaces)
    • action: add the key to the parent zone
    • after the DS TTL has passed, it is considered published and the zone is secured with the key
    • action: wait for the next rollover
  • inactive state:
    • the key is no more used to sign but still published
    • action: remove the DS key from the parent zone
  • deleted state:
    • the key is not published anymore
    • action: when you're sure everything went fine, purge old keys (should be automated some day)

Currently we need to check manually when to do the KSK rollover. The coverage command above and next key event in the zone info should help build a little script to warn us in time.

The plan in the long run is to use CDS/CDNSKEY (RFC 7344). Some interesting reading about an implementation:

Checking a Zone

Test a Zone using a DNSSEC-enabled resolver:

dig <zone-name> +dnssec

You need to get the ad flag. If you get the aa flag, then you're interrogating one of the official NS for the zone, then try on another server to be sure your configuration is OK (remotely with @<server> as first command option).

Test a Zone using an external web tool:

Forcing a policy change to be applied at once

Via Ansible it is possible to change the policy directly, then either wait a few hours or run dnssec-keymgr manually (as bind user).

Unsecuring a Zone

First the DS needs to be removed from the parent zone, then we need to wait for the DS TTL to expire before unsigning.

The Ansible config can then be updated. Key materials need to be removed manually.

Forcing an Early Rollover

It is possible to do so:

  • create new key: dnssec-keygen -a RSASHA512 -b 4096 -3 -f KSK <zone-name> (in /etc/bind/keys and ensuring proper permissions for Bind)
  • resign the zone: rndc sign <zone-name>
  • publish the key in the parent zone (see KSK Rollover Workflow above)
  • schedule removal of the old key: dnssec-settime -D +24h <ksk-filename> (the exact time depends on the TTL of the DS record, which is 24h for Gandi)

Checking Servers


Should return a A record and have the ad flag set:

dig @

Should return SERVFAIL:

dig @


receive_secure_serial: not exact

This means the inline-signing journal is corrupted and changes to the zone cannot be applied to the signed zoned.


rndc sync -clean <zone>
rndc stop

then bump the zone's serial and restart Bind, it should have solved the problem.

If this does not work:

systemctl stop bind9
rm /var/cache/bind/masters/<zone>.zone.*
systemctl start bind9

Updated by Marc Dequènes 12 months ago · 22 revisions