DNSSEC (DNS Security Extensions) protects DNS data integrity by cryptographically signing zone records. But managing the signing keys — especially rotating them on schedule without breaking validation — is one of the most error-prone operations in DNS administration. This guide compares how BIND, Knot DNS, and PowerDNS handle DNSSEC key rollover automation, including their built-in tools, configuration approaches, and operational trade-offs.

What Is DNSSEC Key Rollover?

DNSSEC uses two key types: the Zone Signing Key (ZSK) for signing individual records, and the Key Signing Key (KSK) for signing the ZSK. Both keys must be rotated periodically for security compliance. The rollover process involves generating a new key, publishing it alongside the old one (the “pre-publish” phase), switching signatures to the new key, and finally removing the old key from the zone (the “retirement” phase).

Two rollover algorithms exist: pre-publish rollover (generate new key, wait for old TTL to expire, then switch signatures) and double-signature rollover (sign with both keys simultaneously during the transition). KSK rollovers additionally require updating the DS record in the parent zone, which introduces a coordination dependency.

A failed rollover can cause your entire zone to become unvalidated — meaning DNSSEC-aware resolvers will reject your records entirely. Automation is critical for avoiding outages.

BIND: Manual Automation with dnssec-keymgr

BIND 9 has long been the reference DNS implementation. Its DNSSEC key management relies on dnssec-keymgr, a script that automates key generation, timing, and rollover based on configured key lifecycle policies.

Key Configuration

BIND stores keys in the directory specified by key-directory and uses auto-dnssec maintain to trigger automatic signing:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
options {
    key-directory "/var/named/keys";
};

zone "example.com" {
    type master;
    file "/var/named/example.com.zone";
    auto-dnssec maintain;
    inline-signing yes;
    key-directory "/var/named/keys";
};

Rollover Process

dnssec-keymgr reads timing metadata from .key and .private files to determine when to generate, activate, or retire keys:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Generate KSK with 2-year lifetime
dnssec-keymgr -K /var/named/keys -a RSASHA256 -b 2048 -f KSK example.com.

# Generate ZSK with 3-month lifetime
dnssec-keymgr -K /var/named/keys -a RSASHA256 -b 1024 example.com.

# Set key timing
dnssec-keymgr -K /var/named/keys -P publish example.com.+008+12345
dnssec-keymgr -K /var/named/keys -A activate example.com.+008+12345
dnssec-keymgr -K /var/named/keys -D delete example.com.+008+12345

BIND’s rndc sign command triggers re-signing when key metadata changes. The dnssec-policy directive (introduced in BIND 9.16) allows declarative key lifecycle management:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
dnssec-policy "standard" {
    keys {
        ksk lifetime unlimited algorithm ecdsap256sha256;
        zsk lifetime P30D algorithm ecdsap256sha256;
    };
    max-zone-ttl PT3600S;
    parent-ds-roll 48h;
    parent-propagation-delay 2h;
    publish-safety P7D;
    retire-safety P7D;
    signatures-refresh P14D;
    signatures-validity P30D;
};

This policy-based approach is the most automated BIND offers — keys are generated, activated, and retired on schedule without manual intervention.

Docker Compose Deployment

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
services:
  bind9:
    image: ubuntu/bind9:latest
    container_name: bind9-dnssec
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "953:953/tcp"
    volumes:
      - ./named.conf:/etc/bind/named.conf
      - ./zones:/etc/bind/zones
      - ./keys:/etc/bind/keys
    environment:
      - BIND9_USER=root
    restart: unless-stopped

Strengths and Limitations

BIND’s dnssec-policy provides a declarative approach that handles the full KSK and ZSK lifecycle automatically. The parent DS record roll timing is configurable, and the mature ecosystem means extensive documentation and community knowledge. However, the policy system is relatively new (BIND 9.16+), manual key management with dnssec-keymgr is still the default for older versions, and the key timing metadata system can be opaque when things go wrong.

Knot DNS: Automatic DNSSEC with KASP

Knot DNS was designed from the ground up with automated DNSSEC as a first-class feature. Its Key And Signature Policy (KASP) engine handles the complete key lifecycle without external scripts.

Key Configuration

Knot DNS configures DNSSEC entirely within its YAML configuration file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
template:
  - id: default
    storage: "/var/lib/knot"
    file: "%s.zone"
    dnssec-signing: on
    dnssec-policy: "default"

policy:
  - id: default
    dnssec: on
    algorithm: ECDSAP256SHA256
    ksk-size: 256
    zsk-size: 256
    dnskey-ttl: 3600
    zone-max-ttl: 86400
    propagation-delay: 120
    nsec3: on
    nsec3-iterations: 5
    nsec3-salt-length: 16
    nsec3-salt-lifetime: P30D

Automatic Rollover

Knot DNS automatically manages key generation, signing, and rollover based on the policy parameters. No manual key generation or timing commands are needed:

1
2
3
4
5
6
7
8
# Enable DNSSEC for a zone (keys are auto-generated)
knotc zone-set example.com dnssec-policy default

# View current keys and their states
knotc zone-keys example.com

# Check signing status
knotc zone-status example.com

Knot DNS uses the key-tag convention and automatically publishes new keys before activating them (pre-publish rollover). For KSK rollovers, it generates the new KSK, waits for the parent propagation delay, and then submits the DS record update notification.

Docker Compose Deployment

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
services:
  knot-dns:
    image: cznic/knot:latest
    container_name: knot-dns
    ports:
      - "53:53/tcp"
      - "53:53/udp"
    volumes:
      - ./knot.conf:/etc/knot/knot.conf
      - ./zones:/var/lib/knot/zones
      - ./keys:/var/lib/knot/keys
    restart: unless-stopped

Strengths and Limitations

Knot DNS offers the most hands-off DNSSEC experience of the three — enable a policy and the engine manages everything automatically. The YAML configuration is clean and readable, key states are queryable via knotc, and the NSEC3 parameters are tunable within the policy. However, the automation is less transparent than manual approaches, making debugging more difficult, and KSK rollover requires manual DS record submission to the parent registry even though the new key is auto-generated.

PowerDNS: DNSSEC with pdnsutil and the API

PowerDNS Authoritative Server separates DNSSEC management into two paths: the pdnsutil command-line tool for manual operations and the REST API for programmatic automation.

Key Configuration

PowerDNS enables DNSSEC per-zone with pdnsutil or via the API:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Enable DNSSEC on a zone
pdnsutil secure-zone example.com

# Show current keys
pdnsutil list-keys example.com

# Generate a new KSK
pdnsutil generate-key example.com 2048 ksk ecdsap256sha256

# Generate a new ZSK
pdnsutil generate-key example.com 256 zsk ecdsap256sha256

Automated Rollover via the API

PowerDNS 4.0+ introduced the DNSSEC API, enabling fully automated rollover workflows:

1
2
3
4
5
6
7
8
# Get zone DNSSEC info
curl -s -H "X-API-Key: secret" http://localhost:8081/api/v1/servers/localhost/zones/example.com | jq '.dnssec, .dnssec_key_info'

# Create a new key (auto-activates on next signature refresh)
curl -s -X POST -H "X-API-Key: secret" http://localhost:8081/api/v1/servers/localhost/zones/example.com/cryptokeys   -d '{"keytype": "ksk", "active": true, "algorithm": "ecdsa256"}'

# Deactivate a key (triggers retirement after publish-safety period)
curl -s -X PATCH -H "X-API-Key: secret" http://localhost:8081/api/v1/servers/localhost/zones/example.com/cryptokeys/<id>   -d '{"active": false}'

For full automation, combine the API with a cron job or orchestration tool:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/bin/bash
# Automated KSK rollover script for PowerDNS
ZONE="example.com"
API_KEY="secret"
API_URL="http://localhost:8081/api/v1/servers/localhost/zones/$ZONE/cryptokeys"

# Generate new KSK
curl -s -X POST -H "X-API-Key: $API_KEY" "$API_URL"   -d '{"keytype": "ksk", "active": true, "algorithm": "ecdsa256"}'

# Wait for parent propagation (48 hours in production)
sleep 172800

# Deactivate old KSK (PowerDNS handles the retirement timeline)
OLD_KEY=$(curl -s -H "X-API-Key: $API_KEY" "$API_URL" | jq -r '.[] | select(.active == true and .keytype == "ksk") | .id' | head -1)
curl -s -X PATCH -H "X-API-Key: $API_KEY" "$API_URL/$OLD_KEY"   -d '{"active": false}'

Docker Compose Deployment

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
services:
  pdns:
    image: pschiffe/pdns-mysql:latest
    container_name: powerdns-authoritative
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "8081:8081/tcp"
    environment:
      - PDNS_gmysql_host=db
      - PDNS_gmysql_port=3306
      - PDNS_gmysql_user=pdns
      - PDNS_gmysql_password=pdns
      - PDNS_gmysql_dbname=pdns
      - PDNS_api=yes
      - PDNS_api-key=secret
      - PDNS_webserver=yes
      - PDNS_webserver-address=0.0.0.0
      - PDNS_dnssec=backend
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: mariadb:10.11
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: pdns
      MYSQL_USER: pdns
      MYSQL_PASSWORD: pdns
    volumes:
      - pdns-data:/var/lib/mysql
    restart: unless-stopped

volumes:
  pdns-data:

Strengths and Limitations

PowerDNS provides the most flexible automation path — the REST API enables integration with any orchestration system, CI/CD pipeline, or custom tooling. The API gives fine-grained control over every aspect of key lifecycle, and the MySQL backend supports high-availability multi-primary deployments. The tradeoff is that PowerDNS has no built-in policy engine like Knot’s KASP or BIND’s dnssec-policy — you must implement the rollover logic yourself via API calls, and pdnsutil is intentionally manual.

Comparison Table

FeatureBINDKnot DNSPowerDNS
Policy Enginednssec-policy (9.16+)KASP (built-in)None (API-driven)
Automatic KSK GenerationYes (with policy)YesManual or via API
Automatic ZSK RolloverYes (with policy)YesManual or via API
DS Record NotificationConfigurable delayManual submissionManual or via API
Key State Visibilitydnssec-keymgr metadataknotc zone-keysAPI / pdnsutil list-keys
NSEC3 ConfigurationInline in policyInline in policypdnsutil / API
Algorithm SupportRSA, ECDSA, Ed25519RSA, ECDSA, Ed25519RSA, ECDSA, Ed25519
HA DeploymentMulti-primary (limited)Single primaryMulti-primary (MySQL backend)
Docker Official Imageubuntu/bind9cznic/knotpschiffe/pdns-mysql
GitHub StarsISC (project)CZ-NIC (189)PowerDNS (1,600+)
LicenseMPL 2.0GPLv3GPLv2

Choosing the Right DNSSEC Rollover Strategy

BIND is the best choice if you’re already running BIND 9.16+ and want declarative policy management without external tooling. The dnssec-policy system handles the full lifecycle, and the parent DS roll timing is configurable within the policy. It’s the most “set it and forget it” approach for organizations already standardized on BIND.

Knot DNS is ideal for teams that want the simplest possible DNSSEC setup. Enable a policy, configure key sizes and algorithms, and the KASP engine handles everything automatically. The tradeoff is reduced visibility into the rollover state — you query knotc for current status but don’t control individual timing steps. For teams that value simplicity over granular control, Knot DNS is the clear winner.

PowerDNS is the right choice when you need programmatic control over every aspect of DNSSEC key lifecycle. The REST API enables integration with external KSK management systems, automated DS record submission workflows, and custom compliance reporting. If you’re building a DNSSEC operations platform or need multi-primary HA with automated key distribution, PowerDNS is the most extensible option.

Why Self-Host DNSSEC Management?

Running your own DNSSEC-enabled authoritative server gives you complete control over key lifecycle timing, algorithm selection, and compliance with your organization’s security policies. When you rely on a registrar’s DNSSEC management, you’re constrained by their supported algorithms, rollover schedules, and DS record update procedures. Self-hosted DNSSEC means you can implement automated KSK rollover on your own timeline, choose ECDSA or Ed25519 based on your security requirements, and integrate DNSSEC operations into your broader security automation pipeline.

For DNS infrastructure management, see our authoritative DNS server comparison and DNS-over-QUIC setup guide. If you need DNS anycast deployment, check our Bird/FRR anycast guide.

FAQ

How often should I rotate DNSSEC keys?

ZSK rotation depends on your security policy — common intervals are 30-90 days. KSK rotation is less frequent, typically every 1-2 years. The key is to automate the process so that rollover timing is never a manual emergency.

What happens if a DNSSEC rollover fails?

If a rollover fails — for example, if the new key isn’t published before the old key is retired — DNSSEC-aware resolvers will reject your zone’s signatures. This means your domain becomes unreachable for users with DNSSEC validation enabled (increasingly common with Cloudflare, Google, and Quad9 resolvers).

Do I need to manually update the DS record at my registrar?

For KSK rollovers, yes — the parent zone (your registrar or TLD operator) must have the new DS record before you retire the old KSK. BIND and Knot DNS handle the timing, but the actual DS submission to the parent is a manual step (or requires registry API access).

Can I use Ed25519 for DNSSEC signing?

Yes, all three servers support Ed25519 (algorithm 15). It produces smaller signatures than RSA and is computationally faster to verify. Ed25519 is recommended for new deployments unless you have specific interoperability requirements.

Does DNSSEC impact DNS query performance?

DNSSEC adds signature data to DNS responses, increasing packet size. For most queries, the overhead is negligible (a few hundred bytes). The signing computation is done once per zone change, not per query, so there’s no per-query CPU cost.

What is the difference between pre-publish and double-signature rollover?

Pre-publish rollover publishes the new key first, waits for caches to expire, then switches signatures. Double-signature rollover signs with both keys simultaneously during the transition. Pre-publish is simpler and produces smaller responses, while double-signature is more conservative but generates larger DNS responses during the transition.