Why a KSK rollover is not a ZSK rollover
Zone signing keys and key signing keys fail in different ways, and the difference matters more than any configuration detail. A ZSK signs the zone’s ordinary data; the RRSIG and the DNSKEY that validates it both come from the same zone, so a caching resolver either has both or can fetch both from the same authoritative server. A KSK signs only the DNSKEY RRset, and trust in that KSK comes from outside the zone: either a DS record in the parent zone or a trust anchor configured directly in the resolver. RFC 7583 states the split plainly: “A ZSK is used to authenticate information within the zone; a KSK is used to authenticate the zone’s DNSKEY RRset.”
The consequence is that a KSK rollover is a two-zone operation. RFC 7583 again: when trust comes via a DS record, “the rollover algorithm will need to involve the parent zone in the addition and removal of DS records, so timings are not wholly under the control of the zone manager.” For a small operator, that sentence is the whole article. The signing server is the part you control. The registrar’s DS update is the part you do not.
This is why the common framing — “the KSK rotation that breaks resolvers” — is misleading. A correctly sequenced rollover does not break resolvers. A rollover that changes the parent DS before the new DNSKEY is visible, or retires the old KSK before the old DS has expired from caches, produces a window in which a validating resolver holds a DS that points at a key it cannot find, or a DNSKEY RRset signed only by a key the parent does not vouch for. Either state is bogus, and bogus means SERVFAIL for every name in the zone. The failure is a sequencing failure, not a property of KSK rollovers in general.
The three KSK rollover methods, and which one fits a small domain
RFC 7583 describes three methods. It presents them; it does not recommend one. The choice is an operational one.
- Double-KSK. The new KSK is added to the DNSKEY RRset and the RRset is signed with both keys. After the old RRset has expired from caches, the DS record in the parent is changed. After a further interval for that change to be reflected in caches, the old key is removed.
- Double-DS. The new DS record is published first. After it propagates, the KSK is changed. After the old DNSKEY RRset expires from caches, the old DS is removed.
- Double-RRset. The new KSK is added and the DNSKEY RRset signed with both keys, and the new DS is added to the parent at the same time. After a suitable interval, the old DNSKEY and DS records are removed.
For a domain served by one or two authoritative servers and registered through a registrar whose DS interface is a web form, Double-KSK is the method that keeps the risky step isolated. Everything before the DS change is reversible: if the new KSK turns out to be wrong, you retire it and nothing has touched the parent. Everything after the DS change depends on the new key staying valid. Double-DS inverts that: the parent is changed first, and the child has to catch up. Double-RRset changes both sides at once, which is fine if you can coordinate them and unpleasant if you cannot.
The recommendation here is Double-KSK for small operators, not because RFC 7583 prefers it but because it puts the irreversible step last and gives you a clean rollback point before it.
Manual key management in Knot DNS, and why it is worth the extra steps
Knot DNS supports automatic DNSSEC signing in two modes. The documentation describes manual key management as follows: “the server maintains zone signatures (RRSIGs) only. The signatures are kept up-to-date and signing keys are rolled according to the timing parameters assigned to the keys. The keys must be generated and timing parameters must be assigned by the zone operator.” Automatic key management, by contrast, generates and rolls keys according to a policy with no operator intervention.
For a KSK rollover on a domain you log into twice a year, manual management is the better default. It forces you to look at the key states between transitions. An automatic rollover you never inspect is a rollover you cannot debug when a resolver starts returning SERVFAIL and you are not sure which key is live. Manual management also makes the DS step an explicit action rather than a side effect of a timer.
A minimal policy for manual management looks like this:
policy:
- id: manual
manual: on
zone:
- domain: example.com
dnssec-signing: on
dnssec-policy: manual
Keys are then generated with keymgr. The KASP database that holds them is LMDB-backed and, without an HSM, contains private key material; the Knot documentation warns explicitly: “If no HSM is used, the database also contains private key material – don’t set the permissions too weak.”
Walking the Double-KSK sequence with keymgr
The example below is a hypothetical walkthrough built from documented keymgr primitives. It is not a report of a specific rollover. The timestamps are illustrative; substitute your own TTLs and registrar latency.
Knot’s key states, as documented in the keymgr manual, include publish, ready, active, retire, and remove. For a KSK, ready is described as “Key is waiting for submission (only for KSK).” That state is the hinge of the whole procedure: it is where the child zone has published the new key and is waiting for the parent to vouch for it.
Step 1: generate the new KSK, published but not active
keymgr example.com. generate algorithm=ECDSAP256SHA256 ksk=yes publish=now active=+2d
The new KSK appears in the DNSKEY RRset immediately. The DNSKEY RRset is signed with both the old and new KSK during this window. No DS change has happened yet. If anything looks wrong, delete the new key and nothing outside your zone has changed.
Step 2: wait out the DNSKEY TTL
RFC 7583 assumes constant TTLs in its timelines and notes that changing TTLs around a rollover “may have an impact on event timings.” Do not change TTLs during the rollover. Wait at least the DNSKEY RRset TTL, plus whatever margin you trust, so that any resolver holding a cached DNSKEY RRset has seen both keys. The active=+2d above is a placeholder for that interval.
Step 3: verify the new key is visible from outside
Query your authoritative server directly for the DNSKEY RRset and confirm both KSKs are present. Then query a public validating resolver for the same RRset and confirm it returns both keys with a valid signature. Your local resolver’s cache is exactly the thing that hides rollover mistakes, so do not use it as the only check.
Step 4: change the DS record at the registrar
This is the step that is not under your control. Generate the DS for the new key:
keymgr example.com. ds <new_key_id>
Submit it to the registrar. The Knot documentation is explicit about the timing constraint: “Remember to update the DS record in the parent zone to include a reference to the new key. This must happen within one day (in this case) including a delay required to propagate the new DS to caches.” The “one day” there is the example’s window, not a universal rule; the real constraint is whatever interval you set between active and retire on the old key, minus DS propagation time.
If your registrar supports publishing both the old and new DS simultaneously, do that. If it only supports replacing one DS with another, you are relying on the parent’s negative caching and the child’s dual-signed DNSKEY RRset to cover the gap. That is the standard Double-KSK assumption, but it is worth knowing which case you are in before you submit.
Step 5: wait for the new DS to propagate
Query the parent zone directly for the DS RRset and confirm the new DS is present. Then query a public validating resolver and confirm it validates the chain. Only after both checks pass should you schedule the old key’s retirement.
Step 6: retire the old KSK
keymgr example.com. set <old_key_id> retire=+2d remove=+4d
The old key remains published until retire, then is removed at remove. The gap between the two is the window in which the old DNSKEY RRset expires from caches. Do not shorten it because the rollover “feels done.”
What “safe” means, and why the schedule is secondary
RFC 7583 is direct about the goal: “the point of key management logic is not to ensure that a rollover is completed at a certain time but rather to ensure that no changes are made to the state of keys published in the zone until it is ‘safe’ to do so (‘safe’ in this context meaning that at no time during the rollover process does any part of the zone ever go bogus).”
That reframes the whole exercise. You are not trying to hit a date. You are trying to avoid any moment when a validating resolver holds a DS that does not match a published DNSKEY, or a DNSKEY RRset signed only by a key the parent does not vouch for. Every step above is a wait for caches to converge, not a wait for a calendar.
The same RFC notes that a slow parent is not itself a problem: “even with a parent that is less than ideally responsive, the only effect will be a slowdown in the rollover state transitions. This may cause a policy violation, but will not cause any operational problems.” A registrar that takes three days to publish a DS does not break your zone. A registrar that takes three days while you have already retired the old KSK does.
Verification checkpoints between steps
The checks that matter are the ones run from outside your own network. A short list:
- After step 1: query the authoritative server for the DNSKEY RRset and confirm both KSKs are present. Query a public validating resolver and confirm it returns the same RRset with a valid signature.
- After step 4: query the parent zone directly for the DS RRset and confirm the new DS is present. Query a public validating resolver for a name in your zone and confirm it returns an answer, not SERVFAIL.
- After step 6: query a public validating resolver for a name in your zone again. If it returns SERVFAIL, the old key was retired before the old DS expired from caches, or the new DS was never accepted.
If the registrar is slow, the correct response is to extend the interval before retire on the old key, not to shorten it. The old key is doing useful work as long as the old DS may still be cached somewhere.
Rollback before and after the DS change
Before the DS change, rollback is trivial: delete the new KSK and the zone returns to its previous state. Nothing outside your zone has changed.
After the DS change, rollback is not trivial. If the new KSK turns out to be wrong, you have two options: re-publish the old KSK and submit its DS again, or fix the new key in place. The first is faster if the old key is still in the KASP database and still published; the second is safer if the old key was already retired. Either way, the window between the DS change and the old key’s retirement is the only period in which rollback is cheap. Treat it as such.
When automatic KSK management is the right call
Knot supports automatic KSK management through a submission section pointing at the parent zone server, combined with a finite ksk-lifetime in the policy. The documentation describes this as “semi-automatic DS submission.” The word “semi” is doing real work: the server can publish the new key and prepare the DS, but the actual submission to the registrar is still an operator action unless your registrar exposes an interface Knot can drive.
Automatic management is reasonable when you have a registrar with a reliable API, a monitoring system that alerts on DNSSEC validation failures, and enough rollover frequency that manual steps become a burden. For a domain rolled once a year, the manual sequence above is shorter than the time it takes to debug an automatic rollover that stalled at ready because the parent never accepted the DS.
What you give up with automatic management is observability between states. The server will not tell you that the DS step is the one that failed; it will tell you that the key is still in ready. That is a fine signal if you have a runbook for it and a poor one if you do not.
Scope limits worth knowing
RFC 7583 explicitly scopes out two cases that small operators sometimes conflate with KSK rollover: “it does not cover: rolling a key that is used as both a ZSK and KSK” and “algorithm rollovers.” If you are using a single CSK, the KSK timelines in RFC 7583 do not apply to it. If you are changing algorithms, the constraints are different and the RFC says so. Do not borrow the Double-KSK sequence for either case and expect it to hold.
The other scope limit is TTLs. The RFC assumes constant TTLs in its timelines. If you have been meaning to lower your DNSKEY TTL, do it before the rollover, not during it.
FAQ
Can I skip the wait between publishing the new KSK and changing the DS?
Only if you are certain no resolver holds a cached DNSKEY RRset that lacks the new key. In practice that means waiting at least the DNSKEY TTL. Skipping the wait produces a window in which a resolver has the new DS but not the new DNSKEY, which is bogus.
What happens if my registrar publishes the new DS but not the old one?
You are relying on the child’s dual-signed DNSKEY RRset to cover the gap. That is the standard Double-KSK assumption. It works as long as the old KSK is still published and the old DS has not yet expired from caches. Do not retire the old KSK until you are confident both conditions hold.
How do I know the rollover succeeded?
A public validating resolver returns an answer, not SERVFAIL, for a name in your zone, and a direct query to the parent returns the new DS. Both checks, from outside your network, after each step.
Is automatic KSK management safe for a small domain?
It is safe in the sense that Knot will not change key states until it considers them safe. It is less safe in the sense that the DS submission step still depends on your registrar, and a stalled submission is easier to miss when no one is watching the key states. Manual management is the better default for infrequent rollovers.
Sources
- RFC 7583, DNSSEC Key Rollover Timing Considerations, Morris et al., October 2015. https://www.rfc-editor.org/rfc/rfc7583
- RFC 6781, DNSSEC Operational Practices, Version 2, Kolkman et al., December 2012. https://www.rfc-editor.org/rfc/rfc6781
- Knot DNS 3.6 documentation, Configuration, automatic DNSSEC signing and key management sections. https://www.knot-dns.cz/docs/latest/html/configuration.html
- Knot DNS 3.6 documentation, keymgr – Key management utility. https://www.knot-dns.cz/docs/latest/html/man_keymgr.html