DNSSEC is cool. It easily adds security to probably the most important enabling protocol in today’s Internet: No web pages could be found, email delivered, or instant message received, without the Domain Name System (DNS). DNSSEC also enables DANE, a step forward for certificates for most applications. Sometimes you want to change a few settings. DNSSEC is very forgiving, except when changing algorithms. Here is how.
DNSSEC transitions: The good
DNSSEC transitions can occur frequently, and should:
- The Zone Signing Key (ZSK) should be changed regularly (e.g. every 1-12 months) to make attacks harder. Because the ZSK is used for every entry in your zoneA zone often matches a domain, sometimes including subdomains, it can be cryptanalyzed more easily„Easy“ being relative here. Probably still requiring gazillions of CPU years.. It is also easiest to change, because it just needs to be published in your zone, signed with your KSK (see below).
- The Key Signing Key (KSK) should also be changed in larger intervals. Its change also requires updating the DSDelegation Signer entry in the parent zone, a change which must be executed by your registrar. As of today, this cannot be automated with most registrars, so it probably will break down to occurring only every few years.
For a change to these keys, you generate a new one, add it to the list, and after some time (at least equal to the longest time-to-live (TTL) in your zone), you remove the old key and its entries. Having any key which is signed by any of the higher-level keys or any signature signed by any of the ZSKs being valid, makes the entry valid. In effect, if there is any valid path from the root to the entry, the entry is valid.
So far, so simple. And good.
DNSSEC transitions: The bad
Obviously, something was missing from the good list above. Obviously, it is not good.
- Changing the signature algorithm. Once in a while, you might want to update the algorithm which was used to sign the keys and entries. For example, the old algorithm might have been broken by researchers. Or you want to switch to a more efficient algorithm (faster, fewer bits). Or to a more capable one. Or the name of the newer algorithm just sounds cooler.
Then you better brace yourself, the ride will be rough.
In theory, the same applies as above: As long as there is one valid path from the root to your entry, the entry is valid. However, not all software (especially resolvers) will understand all algorithms. The only required algorithm is RSA/SHA-1 (algorithm number 5), which has a weak hash function, allows enumeration of all DNS entries, and comes with long signatures, leading to the possibility of amplification DoS attacks. Not everyone’s favorite, but the baseline to get started. People started using the (recommended) algorithms RSASHA1-NSEC-SHA1 (algorithm 7) to prevent enumeration or ECDSA Curve P-256 with SHA-256 (algorithm 13) to get a stronger hash and shorter signatures (and, in turn, shorter DNS response packets).
Because they are not required, not all software clients understand them. Here is how to deal with it:
Zone with only unknown algorithms
To allow the introduction of new algorithms without first having to change the software on all the billions of Internet-connected devices, a transition mechanism is in place: If, while traversing the path from the root to the entry in question, a zone specifies only algorithms which the client does not understand, it should treat that zone as if it were unsigned. By default, unsigned zones are considered to be valid, as otherwise the transition from legacy DNS to DNSSEC would be impossible.
Zone with mixed known/unknown algorithms
With mixed known and unknown mechanisms, while there might be a valid path from the root to the entry, not all client software will find it. To deal with this case, the signer has to make sure that every algorithm listed signs with (at least) one of the keys for this algorithm. This is to prevent downgrade attacks to weak or broken algorithms.
Successful algorithm transition How-To
The client should again only verify whether a valid path exists, but as we do not know what the clients support, we need to be careful. To successfully transition to a new algorithm, use the following steps:
- Shorten the TTL of the old DS entry, if possible
- Create a new KSK and ZSK for the new algorithm
- Sign the ZSK with the KSK and the zone with the ZSK
- Add the DS entry for the new ZSK in the parent zone
- Wait for all involved TTLs to expire: Ensure the new entries are (also) in the caches
- Remove the DS entry associated with the old algorithm
- Wait for the old DS entry’s TTL to expire: Ensure it has been flushed from all caches
- Remove the keys and signatures associated with the old algorithm
DNSSEC transitions: The ugly
This is not a DNSSEC problem per se, but as DANE only makes sense with DNSSEC, we list it here: Adapting the DANE TLSA entries when refreshing Let’s Encrypt certificates. Let’s Encrypt certificates typically are automatically installed and activated on renewal, but the old TLSA record is still in place. Anyone verifying against a cached DANE re source record (RR) will thus refuse the connection, as it looks as if the domain had been hijacked or a man in the middle is attacking.
Therefore, it is recommended to avoid the common „3 0 1“ and „3 0 2“ TLSA entries (specifying the SHA-256 or SHA-512 fingerprint of the host’s certificate itself). Instead, the following two alternatives are described:
- Publish „3 1 1″/“3 1 2“ entries (fingerprint of the public key only, not the entire certificate) and instruct the Certbot ACME client to not generate a new keypair.acme.sh, an alternative Let’s Encrypt/ACME client which I use for its support for DNS verification, does not create new keys unless
--always-force-new-domain-keyis given. You might want to give it a try, as I feel it makes automation easier in many aspects.
- Publish „2 1 1“ entries (fingerprint of the CA public key) and hope that it does not change anytime soon.
Most traditional TLS key pairs live many years anyway, so not changing them every 60-90 days is just fine, making option 1 above an exquisite option. Using „2 1 1“ works well, if you can actually create certificates with all the service names in them, as all certificate usages beside 3 will perform name and validity verification with the returned TLS certificate.Updated 2017-08-29: Corrected my misunderstanding that certificate usage 2, similar to 3, would not perform name checks.
As again, any valid path to the actual certificate is valid, it is recommended to have both a „2 1 1“ and a „3 1 1“ TLSA entry associated with your service. A concrete example for the Postfix mail server is described and explained here.