All hardcore security enthusiasts would know that TLS authenticated by a DANE trust anchor signed with DNSSEC provides much better security assurance than TLS authenticated by PKIX trust stores with hundreds of root CA anchors. In fact, one could consider TLS without DANE as an illusion of security, that can be easily bypassed by governments and other sophisticated adversaries.
Thanks to the championing by Victor Duknovny @ietf-dane (who wrote RFC 7671 and RFC 7672 and implemented DANE support for Postfix MTA), the adoption of DANE has been steadily growing, especially for securing of otherwise insecure email servers (Opportunistic DANE is a lot more secure than Opportunistic TLS, especially without MTA-STS).
There are many different ways to implement DANE, but the most secure of them is to use 3 1 1 or 3 1 2 TLSA trust anchor records to pin down the actual keys that your server certificate uses. Of course in cryptography all keys have a shelf life, and it is a good practice to regularly rotate the certificate keys.
Unfortunately, DNS propagation time and DNS cache expiration presents a challenge for 3 1 1 and 3 1 2 TLSA records keys rollover. Because of this, many people chose to deploy DANE with a bit less secure 2 1 1 records pinning the issuing CA as the trust anchor. These people soon will find out that this presents its own issues highlighted by Victor in this thread.
In the 2018 ICANN61 conference Victor has presented a Current + Next DANE key rollover procedure which addresses this challenge by publishing TLSA records for pre-generated keys which will be used for the next certificate renewal.
I thought I'd share a practical way of how to do Current + Next DANE key rollover with Let's Encrypt certificates.
Some of you may be familiar with an excellent acme.sh client developed by @Neilpang as an alternative to the Certbot client. acme.sh
allows forcing of new keys generation during certificate renewals as well as DNS01 challenge that would be close to heart for DANE users.
Earlier in the year I raised an issue #3096 ticket for acme.sh to request pre-generation of keys during issuance for future certificate renewals. @Neilpang was a good sport and created a new Github branch with this feature implemented.
I have been successfully running Victor's Current + Next DANE key rollover using this version of acme.sh
ever since, and I thought it would be useful to share this with the broader Let's Encrypt community.
Please note that this feature has not made it into the official acme.sh
trunk and releases yet.
In the issue link above I have provided a script for updating TLSA records in BIND, as well as a patch with some further acme.sh improvements (hasn't been committed into GitHub). Also I've highlighted some small issues that you need to be careful and watch out for.
For those interested in quickly playing with commands that work without spending too much time on reading acme.sh
documentation, commands for issuing and installing a staging wildcard ECDSA certs using DNS01 challenge with BIND nsupdate
would look something like this:
export NSUPDATE_SERVER="IP.address.of.BIND.name.server"
export NSUPDATE_KEY="/path/to/key/that/grants/access/to/modify/DNS01/challenge/records/acme.key"
export NSUPDATE_ZONE="example.com"
acme.sh --issue -d example.com -d '*.example.com' \
--dns dns_nsupdate --dnssleep 0 \
--ocsp --ecc -k ec-384 -ak ec-384 --always-force-new-domain-key \
--config-home /path/to/acme-sh/config/home --log /var/log/acme.log --staging
acme.sh --install-cert -d example.com \
--cert-file /etc/ssl/example.com-cert.pem \
--key-file /etc/ssl/example.com-key.pem \
--fullchain-file /etc/ssl/example.com-fullchain.pem \
--reloadcmd "/path/to/reloadcmd.sh" --ecc \
--config-home /path/to/acme-sh/config/home --log /var/log/acme.log
Note: you can find an example of the reloadcmd.sh
script that works for me is in the issue ticket link above.
Hope this helps some DNS01 challenge users to take the leap to DNSSEC signed DANE, or move from 2 1 1 TLSA records to 3 1 1 and/or 3 1 2 (I use and rotate both).