8.0 KiB
title | slug | description | date | draft | ShowLastmod | toc | scrolltotop | tags | |||
---|---|---|---|---|---|---|---|---|---|---|---|
How to create or renew a TLSA record for DANE with certificates from Let's Encrypt | create-or-renew-tlsa-records | I had to renew my TLSA records for DNS-based Authentication of Named Entities (DANE) on my server that uses SSL certificates from Let's Encrypt. | 2024-10-03T09:26:58Z | false | true | true | true |
|
I have been operating my own mail server for some 10 years. Recently, some e-mails that others attempted to send to me any my family would not longer be delivered. This is a very unfortunate situation, because most senders will not make a second attempt (e.g., with a different recipient address), leave alone provide you with an error message. However, luckily, this morning (Reunification Day in Germany!), I received this screenshot:
{{< figure src="outlook-error.jpg" alt="(German) screenshot of an e-mail delivery error due to an invalid TLSA record" caption="(German) screenshot of an e-mail delivery error due to an invalid TLSA record">}}
And then it was all clear to me. The resource records (RR) in my domain-name system (DNS) configuration that configure DNS-based Authentication of Named Entities (DANE) were no longer valid. I use certificates issued by Let's Encrypt, and evidently their chain of trust had changed so that the trust anchors that I had written into my DNS records were no longer valid.
Correctly setting up TLSA records for DANE is everything but trivial. After some trial and error, I found the following resource most useful:
https://dnssec-stats.ant.isi.edu/~viktor/x3hosts.html
Key points from this and other pages to remember:
- When using TLSA RR in the form
2 1 1 ...
, i.e., declaring that the payload (...
) of the record is the digest of a "trust anchor", be aware that this must be theSHA256
digest of the public key of your trust anchor. - Let's Encrypt's
certbot
tool places three files on your server:cert.pem
,chain.pem
andfullchain.pem
, wherecert.pem
is the mail server's certificate,chain.pem
is the trust chain excluding the root CA andfullchain.pem
iscert.pem
+chain.pem
. The important bit here is that none of these certificate files contain the root CA! - As a consequence, do not use a digest of Let's Encrypt's root CAs in your TLSA record, unless you want to add that root CA to the certificate files on your server (don't).
- Configure TLSA records for all intermediate CAs, e.g., R10-R14.
Interstingly and embarassingly, the Information Sciences Institute (ISI) on their page linked to above has a list of mail servers that still use a TLSA record with a retired CA from Let's Encrypt -- and that list contains `bovender.de' :-/ I guess it's about time to fix that!
Let's Encrypt's chains of trust
Let's Encrypt's chains of trust are described here:
https://letsencrypt.org/certificates/
For the reasons mentioned above, we are not interested in the root CAs (ISRG Root X1 and ISRG Root X2). Instead, we want to use the digests of the public keys of the subordinate (intermediate) CAs. At the time of writing (2024-10), Let's Encrypt lists four active intermediate CAs:
- E5 and E6 for certificates with ECDSA public keys
- R10 and R11 for certificates with RSA public keys
To find out which of the two algorithms (ECDSA and RSA) was used to generate
your mail server's certificate, ssh into your server, navigate to
/etc/letsencrypt/live/<mailserver-certificate-name>
as root and issue:
$ openssl x509 -in cert.pem -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
03:d3:73:ef:60:97:31:88:bc:e5:31:99:f3:00:d5:b0:c1:92
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, O = Let's Encrypt, CN = R11
Validity
Not Before: Sep 24 22:37:51 2024 GMT
Not After : Dec 23 22:37:50 2024 GMT
Subject: CN = bovender.de
Subject Public Key Info:
# ...
Thus, my mail server's current (!) certificate was issued by R11.
This may be different in the future when the certificate is renewed.
Currently my web server's certificate uses the ECDSA algorithm:
$ cd ../bovender/
$ openssl x509 -in cert.pem -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
04:22:00:17:8a:ed:51:09:56:15:62:2e:b5:85:49:70:05:ac
Signature Algorithm: ecdsa-with-SHA384
Issuer: C = US, O = Let's Encrypt, CN = E6
Validity
Not Before: Aug 19 11:34:11 2024 GMT
Not After : Nov 17 11:34:10 2024 GMT
Subject: CN = bovender.de
This certificate was issued by the E6 intermediate CA.
An alternative way to find out more about a web server's SSL certificate is to
use curl
:
$ curl -I --write-out '%{certs}' https://bovender.de
HTTP/2 301
server: nginx/1.27.1
date: Thu, 03 Oct 2024 09:25:05 GMT
content-type: text/html
content-length: 169
location: https://www.bovender.de/
strict-transport-security: max-age=63072000; includeSubDomains; preload
# ...
Subject:C = US, O = Let's Encrypt, CN = E6
Issuer:C = US, O = Internet Security Research Group, CN = ISRG Root X1
# ...
-----END CERTIFICATE-----
E6 again (surprise!).
The key type that certbot
uses to renew certificates is contained in
/etc/letsencrypt/renewal/<mailserver-certificate-name>.conf
:
$ cat mail.conf
# renew_before_expiry = 30 days
version = 2.11.0
archive_dir = /etc/letsencrypt/archive/mail
cert = /etc/letsencrypt/live/mail/cert.pem
privkey = /etc/letsencrypt/live/mail/privkey.pem
chain = /etc/letsencrypt/live/mail/chain.pem
fullchain = /etc/letsencrypt/live/mail/fullchain.pem
# Options used in the renewal process
[renewalparams]
account = [REDACTED]
authenticator = webroot
server = https://acme-v02.api.letsencrypt.org/directory
key_type = rsa
# ...
The line key_type
declares that RSA be used for my mail server's certificate.
Setting up TLSA RRs in your DNS zone
As advised by ISI.edu, it is best practive to have TLSA records for all possible intermediate CAs as you will never know which intermediate CA will be the next to issue a renewed certificate. This is even more important if you have a cron job set up to automatically renew certificates that are about to expire.
For the record (pun intended), here are my _25._tcp
entries. Everything after
the pound sign (#
) MUST NOT be included in the record, of course.
2 1 1 2bbad93ab5c79279ec121507f272cbe0c6647a3aae52e22f388afab426b4adba # R10
2 1 1 6ddac18698f7f1f7e1c69b9bce420d974ac6f94ca8b2c761701623f99c767dc7 # R11
Following the advice by viktor on ISI.edu, I have left only those two
records in my DNS zone that represent currently used intermediate CAs (R10 and
R11). I know that certbot
will not issue ECDSA certificates for my mail server
because the configuration file (see above) contains the line key_type=RSA
. My
web server has an ECDSA certificate, but I currently see no use for DANE for my
web server as Chrome and Firefox do not support it.
Verify the validity of the TLSA record
To test that DANE works as expected, try one of these sites:
- https://www.mailhardener.com/tools/dane-validator?domain=bovender.de
- https://dane.sys4.de/smtp/bovender.de
Query TLSA records:
"Die Moral von der Geschicht"
"The moral of the story":
- Server administration was, is, and will always be complicated.
- Always mistrust yourself.
- Regularly verify that everything works as expected, especially security-related stuff.
- If something does not work, spend more time researching on the world wide web. I came across the ISI.edu page only after several hours and is was far more useful for me than all the websites and blog and forum posts that I had previously read.