2024-10-03 19:20:07 +00:00
|
|
|
---
|
|
|
|
title: "How to create or renew a TLSA record for DANE with certificates from Let's Encrypt"
|
|
|
|
slug: create-or-renew-tlsa-records
|
|
|
|
description: >
|
|
|
|
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.
|
|
|
|
date: 2024-10-03T09:26:58Z
|
|
|
|
draft: false
|
2024-10-04 05:17:33 +00:00
|
|
|
ShowLastmod: true
|
2024-10-03 19:20:07 +00:00
|
|
|
toc: true
|
|
|
|
scrolltotop: true
|
|
|
|
tags:
|
|
|
|
- server
|
|
|
|
- certificate
|
|
|
|
---
|
|
|
|
|
2024-10-04 05:17:33 +00:00
|
|
|
I have been operating my own mail server for some 10 years. Recently, some
|
2024-10-03 19:20:07 +00:00
|
|
|
e-mails that others attempted to send to me any my family would not longer be
|
2024-10-04 05:17:33 +00:00
|
|
|
delivered. This is a very unfortunate situation, because most senders will not
|
2024-10-03 19:20:07 +00:00
|
|
|
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)][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>
|
|
|
|
|
2024-10-04 05:17:33 +00:00
|
|
|
Key points from this and other pages to remember:
|
2024-10-03 19:20:07 +00:00
|
|
|
|
|
|
|
- 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 the `SHA256` 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` and `fullchain.pem`, where `cert.pem` is the mail server's
|
|
|
|
certificate, `chain.pem` is the trust chain _excluding the root CA_ and
|
|
|
|
`fullchain.pem` is `cert.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!
|
|
|
|
|
2024-10-04 05:17:33 +00:00
|
|
|
## Let's Encrypt's chains of trust
|
2024-10-03 19:20:07 +00:00
|
|
|
|
|
|
|
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
|
2024-10-04 05:17:33 +00:00
|
|
|
your mail server's certificate, ssh into your server, navigate to
|
2024-10-03 19:20:07 +00:00
|
|
|
`/etc/letsencrypt/live/<mailserver-certificate-name>` as root and issue:
|
|
|
|
|
|
|
|
```text
|
|
|
|
$ 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**.
|
|
|
|
|
2024-10-04 05:17:33 +00:00
|
|
|
This may be different in the future when the certificate is renewed.
|
|
|
|
|
|
|
|
Currently my web server's certificate uses the ECDSA algorithm:
|
2024-10-03 19:20:07 +00:00
|
|
|
|
|
|
|
```text
|
|
|
|
$ 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`:
|
|
|
|
|
|
|
|
```plain
|
|
|
|
$ 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`:
|
|
|
|
|
|
|
|
```plain
|
|
|
|
$ 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][isi], 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.
|
|
|
|
|
|
|
|
```plain
|
|
|
|
2 1 1 2bbad93ab5c79279ec121507f272cbe0c6647a3aae52e22f388afab426b4adba # R10
|
|
|
|
2 1 1 6ddac18698f7f1f7e1c69b9bce420d974ac6f94ca8b2c761701623f99c767dc7 # R11
|
|
|
|
```
|
|
|
|
|
2024-10-04 05:17:33 +00:00
|
|
|
Following the advice by _viktor_ on [ISI.edu][isi], I have left only those two
|
2024-10-03 19:20:07 +00:00
|
|
|
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][dane].
|
|
|
|
|
|
|
|
## Verify the validity of the TLSA record
|
|
|
|
|
2024-10-04 05:17:33 +00:00
|
|
|
To test that DANE works as expected, try one of these sites:
|
2024-10-03 19:20:07 +00:00
|
|
|
|
|
|
|
- <https://www.mailhardener.com/tools/dane-validator?domain=bovender.de>
|
|
|
|
- <https://dane.sys4.de/smtp/bovender.de>
|
|
|
|
|
2024-10-04 05:17:33 +00:00
|
|
|
Query TLSA records:
|
|
|
|
|
|
|
|
- <https://www.nslookup.io/domains/_25._tcp.bovender.de/dns-records/tlsa/>
|
2024-10-03 19:20:07 +00:00
|
|
|
|
|
|
|
## "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][isi] 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.
|
|
|
|
|
|
|
|
[dane]: https://en.wikipedia.org/wiki/DNS-based_Authentication_of_Named_Entities
|
|
|
|
[isi]: https://dnssec-stats.ant.isi.edu/~viktor/x3hosts.html
|