Please avoid "3 0 1" and "3 0 2" DANE TLSA records with LE certificates

Executive Summary:

When using LE certificates, which feature 90-day expirations and automated renewal, be sure to avoid publishing “3 0 1” and “3 0 2” DANE TLSA records. Automated renewal of LE certificates will result in a new certificate digest (fingerprint) and willl invalidate your TLSA records.

Instead, publish “3 1 1” or “2 1 1” records as explained in the section below. With “3 1 1” records you’ll need to take steps to ensure that automated renewal of LE certificates does not generate a new private/public key pair, and that instead the same public key pair is used in future updates of the certificate.

Discussion

DANE-EE(3)

One of the most important features of certificate usage DANE-EE(3) TLSA records (see rfc7218, section-2.1) is that for DANE-based verifiers certificates do not automatically expire. Certificates are replaced at the server oeprator’s conveniece, when he is ready to do so, not at a pre-ordained future time he might he might forget.

For certificate usage DANE-EE(3), the certificate expiration is in the RRSIG end time, not in the certificate. Since DNS zone re-signing is (almost universally) automated, DANE-EE(3) TLSA records and the associated certificates continue to work indefinitely.

The price of removing the expiration “time bomb” is that when do you do want to replace the certificate or public key you need to plan ahead. As explained in https://tools.ietf.org/html/rfc7671#section-8.1 the DNS TLSA RRset needs to be updated in advance of certificate replacement by adding a record to match the future certificate or public key a few TTLs before the replacement takes place (start the clock only after all secondary nameservers have the updated versions of the TLSA RRset).

With Let’s encrypt, certificates are comparatively short-lived at 90-days, and are refreshed automatically, perhaps as early as 60 days after they are issued. Any change in the certificate (even if it just the validity dates) changes its digest (SHA2-256 or SHA2-512 digest).

Since the scripts that perform automated LE certificate updates are not designed to make DNS updates, or delay deployment until secondary nameservers catch up and a few TTLs go by after that, it is not possible to publish reliable “3 0 1” or “3 0 2” TLSA records which in effect do remote DNS pinning of the server certificate fingerprint.

One work-around is to publish “3 1 1” or “3 1 2” records which instead “pin” the public key fingerprint. This works, provided you arrange to have a stable public key, which changes only when you decide to manually rekey, at which time you can follow the procedure in RFC7671 to update the TLSA RRset before configuring LE to issue certificates for the new key.

The LE client has a “–csr” option that makes it possible to skip automated key and certificate request (CSR) generation, and instead use a user-provided certficate request (a CSR can be generated once at the same time that the key is created and used repeatedly, or generated each time from the same key).

DANE-TA(2)

Another option is to publish DANE-TA(2) records which pin the fingerprint of the certificate or public key of an issuing certification authority (CA). Note that this requires that the issuing CA certificate be part of your server certificate chain, if it consists of just the leaf (server) certificate you can only use DANE-EE(3) TLSA records (see rfc7671 section-5.2 for details).

So long as automated updates produce new certificates issued by the same CA as before, the same TLSA RRset will validated both the old and the new certificate.

While the LE end-entity (server) certificates have a 90-day expiration, the LE issuing authority has a multi-year lifetime, so it is safer to publish TLSA records of the form:

;subject=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
;issuer= /O=Digital Signature Trust Co./CN=DST Root CA X3
;notBefore=Oct 19 22:33:36 2015 GMT
;notAfter=Oct 19 22:33:36 2020 GMT
;
_dane.example.com. IN TLSA 2 1 1 60B87575447DCBA2A36B7D11AC09FB24A9DB406FEE12D2CC90180517616E8A18
_25._tcp.smtp.example.com. IN CNAME _dane.example.com.
_587._tcp.smtp.example.com. IN CNAME _dane.example.com.
This works much better, but still only postpones the problem. Some day the LE issuing CA certificate will change, and the above TLSA record may stop working without prior notice. The choice of "2 1 1" is deliberate, this continues to work if a future version of the LE CA uses the same public key as before, but has either a new validity period or a new issuer. One might hope the key will be more stable, but there's no way to know this in advance.

It is my hope that this post will encourage LE to provide advance “notice” of their future issuing authority certificates, by enhancing the LE client to optionally generate the relevant “2 1 1” records to add to your zone well in advance of any certificates that use the new issuing authority.

Each site would then need to run the client periodically, and if the generated “2 1 1” records change, make appropriate adjustments to the DNS before the new CA goes into production.

In the mean-time, it is probably best to stick with “3 1 1” and stable keypairs, which you rotate at your own discretion. (see: rfc7671, section-8.1).

Mistakes to avoid: https://dane.sys4.de/common_mistakes, especially #3.

Further reading: rfc7671#section-5.1, rfc7671#section-5.2,
rfc7672#section-3.1.1 and rfc7672#section-3.1.2

16 Likes

FYI Internetsociety.org describes another way how to use DANE with Let’S Encrypt:
https://www.internetsociety.org/deploy360/blog/2016/01/lets-encrypt-certificates-for-mail-servers-and-dane-part-1-of-2/

I think of it as another exposition of the same way, not so much another way...

I used 2 1 1 with the IdenTrust root. The main disadvantage of this, I think, is that you have to send the root in your certificate chain, which is unusual, but shouldn’t cause any problems.

Yes, while including root CAs in the chain may be unusual without DANE, it is required with DANE if you want to use a root CA as a DANE-TA(2) trust-anchor. See:

More recently, an updated post describes the recommended approach in much greater detail. In particular, the new post explains how to use the --csr option. Please see: https://www.internetsociety.org/deploy360/blog/2016/03/lets-encrypt-certificates-for-mail-servers-and-dane-part-2-of-2/

Note: the blog contains links to non-HTTPS images, which are therefore blocked and results in “mixed content” in Chromium.

(Here was a comment advocating against 2 1 1. It was written under the wrong assumption that bits 0 and 1 in the certificate usage field were fully orthogonal, i.e., that 2 and 3 (like 0 and 1) only differed in whether the the certificate/key itself was specified or a parent certificate/key (aka CA). As clarified here, only certificate usage 3 bypasses the name check. So I hereby retract my claim. However, DANE client implementers should watch out for this potential pitfall, to avoid a major security risk.)

Indeed, I was wrong. I have thus updated my previous comment to avoid anyone taking it by face value. Thanks for pointing this out, @tdelmas and @ietf-dane.

1 Like

Ok, so if use '–csr ’ how can i renew the cert it seams to me that is not possible right now with ‘certbot renew’… can i use ‘–reuse-key’ instead to make it work with renew and ‘3 1 1’?

You can use --reuse-key instead of --csr, but the latter prevents you from using renew. You would just need to issue the same command as you did to issue the certificate in order to renew with --csr.

--reuse-key uses much more standard Certbot functionality, so it will manage certificates and enable you to use renew.

Given that you still have the original key, you can generate a CSR from that key, e.g. with:

openssl req -new -key key.pem -config config.cnf -subj "/CN=smtp.example.com" -out csr.pem

where the config.cnf file specifies any additional subject alternative names you might need. You can then use that CSR to get a new certificate for the same key. When you want to switch keys, you generate a new key manually, publish a second TLSA record for the new key, wait for that to age a bit (a few DNS TTLs), and then use “–csr” with a CSR for that key.

You should also consider the approach recommended in my ICANN61 slides: http://imrryr.org/~viktor/ICANN61-viktor.pdf and audio at http://imrryr.org/~viktor/icann61-viktor.mp3

A minor correction: it's certbot renew rather than certbot --renew (renew is considered a subcommand rather than an option).

1 Like

Good point, fixed! Thanks!

So to make it clear, i use the following line:

certbot --nginx --reuse-key -d mydomain.com -d www.mydomain.com

then i publish a ‘3 1 1’ Dane TLSA record, and set a cronjob like:

0 */12 * * * certbot renew --reuse-key

and the TLSA Record will not change so i don’t need to worry about it, right?

Sure, certbot renew --reuse-key sounds much simpler. When I first started this thread almost 3 years ago, certbot was very new, and the only option at the time for keeping the same key seemed to be --csr. Sorry I’ve not kept up with more recent changes…
You should still manually rekey every year or so, with infrequent manual rekeying it should not be difficult to do the DNS TLSA record dance correctly. But see also the ICANN61 slides for additional options.

3 Likes

I did a quick read about dane in some of the links. It is still little bit difficult to set up, but liked a lot the way pointed @ib54003 and @ietf-dane answer.

another iteration of the summary:

[after setting up a letsencrypt cert, that this different on each case]

publish in DNS ‘3 1 1’ Dane TLSA record, can I use output of postfix tls output-server-tlsa ?

edit /etc/cron.d/certbot with 0 */12 * * * certbot renew --reuse-key

last thing is unclear to me: “infrequent manual rekeying” can this by expressed by a cronjob and a simple script?

Thanks!

Yes, once the certificate in question is in live use by Postfix, the command you posted will output its "3 1 1" record with $myhostname as the TLSA base domain. If (atypically) your inbound email arrives to a different name for the host, use that name instead. As for "infrequent manual rekeying", I hope and expect that [not too far in the] future improvements to "certbot" will make that easier. For now it is difficult to automate reliably. See my ICANN61 slides for ideas.