Inhaltsverzeichnis

DANE records with Let's Encrypt

Problem

TLSA records announce what certificate is expected from an endpoint. Since the cert changes often, that can be tricky. One method re-uses the certificate key material so it doesn't change, but that's not very nice. We want to rotate the keys.

Setup

Instead of pinning the cert itself, use DANE-TA(2) to pin the currently active intermediate.

Compute the Intermediate TLSA RR

Find and download the currently used intermediate from LE's published Chain of Trust. Then compute its hash:

url-to-TLSA.sh
#!/bin/bash
 
if [ -z "$1" ] ; then
    echo usage: $0 URL-TO-PEM
    exit 1
fi
 
pkfil=$(mktemp)
trap "[ -f \"$pkfil\" ] && rm -f \"$pkfil\"" EXIT
 
curl "$1" |
  openssl x509 -inform PEM -noout -pubkey > "$pkfil" || { echo "failed to download" ; exit 1 ; }
 
{ openssl rsa -in "$pkfil" -pubin -outform DER || openssl ec -pubin -in "$pkfil" -outform DER ; } |
  openssl dgst -sha256 -hex |
  awk '{print "le-ca TLSA 2 1 1", $NF}'
 ./url-to-TLSA.sh https://letsencrypt.org/certs/gen-y/root-yr-by-x1.pem
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2126  100  2126    0     0  10849      0 --:--:-- --:--:-- --:--:-- 10902
writing RSA key
le-ca TLSA 2 1 1 7e4e8838a8add6295de7ae3b047d3aba3488ab95db0a0aa56d897a00d8618bcf

Next, publish that somewhere such as at the SOA level. Don't forget to put a comment on there and set a calendar reminder to check for the new one in time.

; Let's Encrypt R3 intermediate, expires: 15. September 2025 16:00:00 GMT
le-r3._dane     3600    IN      TLSA    2 1 1 8d02536c887482bc34ff54e41d2ba659bf85b341a0a20afadb5813dcfbcf286d

Finally, point all service records there:

_25._tcp.mx1.sys        IN      CNAME   le-r3._dane.example.com.