Deploy TLSA records (DANE) on your email-server with Let's Encrypt
TLSA records – or more commonly known as DANE(DNS-based Authentication of Named Entities) is a protocol that is being used to “bind” TLS-certificates to a server. It is most used on email-servers to secure communication between different servers. The reason that DANE exist is to provide an additional layer of security and trust between server and client.
In this guide, I will walk your thru the following steps:
- How to check if a SMTP-server uses DANE
- How to configure postfix to start use DANE-verification on outgoing and incoming emails.
- Generation of TLSA-records
- DANE + Let's Encrypt – A Walkaround
Currently, DANE is not something that is widely deployed by big organisations and companies world wide. Instead, smaller companies, organisations and individuals with more flexibility in their IT-infrastructure has been able to contribute to SMTP-security. The only really big company that has announced their plans for a DANE-implementation is Microsoft – they announced their plans for DANE in april 2020 and hope the implementation to be finished in 2021. DANE does also require that the domain is DNSSEC signed for it to work, there is some mail-servers that can do DANE-verification without DNSSEC (like postfix), but I am not going to cover that part today.
But you are not here in order to wait for it to happend! Let's get started!
Does this server have a TLSA-record deployed?
Or, if you are as me – we will do the checks from the terminal with the tools our system provides.
Enter “dig”, a command that can be found in the package “dnsutils” on debian-based systems (“bind-utils” on RHEL based ones). So let's check the TLSA-record of the mailserver of linux.pizza:
dig _25._tcp.kebab.linux.pizza TLSA +short
This gives us the following answer:
3 1 1 2B4685AC11110AC51D117607C0E58D98AF3FD9A417EF3B5B61210578 67D92111
So, what we just did here was checking the host
_25._tcp.hashmal.selea.se for a TLSA record.
The first part – _25. represents the port.
Second part – _tcp. represent the protocol.
The third part – kebab.linux.pizza. represent the actual hostname of the server.
Deploy DANE-verification in postfix
This is probably the easiest step of them all: Add this into your main.cf file
smtp_tls_security_level = dane smtp_dns_support_level = dnssec
Now, postfix does validate DANE for outgoing and incoming SMTP-connections – Nice!
Let's Encrypt + DANE
Since the hash in the TLSA-record is based on the private TLS-key, it does not really make sense to deploy it with Let's Encrypt since Certbot (the most used tool to deploy Let's Encrypt) generates a new private key every time a certificate is being requested.
We will generate the certificate using Certbot, feel free to use whatever client you'd like. Just keep in mind that you have to reuse the same .csr.
We will have to do the issuing and renewal via HTTP/HTTPS, so I assume that you have a webserver installed on your machine.
Create this config-file and place it in a good location (like
domains = mx.your.hostname webroot-path = /path/to/webserver/root rsa-key-size = 4096 email = firstname.lastname@example.org text = True authenticator = webroot renew-by-default = true agree-tos = true
Now, issue your initial certificate:
certbot -c /usr/share/etc/leconfig/mx.your.hostname certonly
Once the certificate have been issued, you can find it in
/etc/letsencrypt/live/mx.your.hostname, for sanity sake, we will copy the entire folder to another location.
mkdir -p /usr/local/etc/letsencrypt/live/ cp /etc/letsencrypt/live/mx.your.hostname /usr/local/etc/letsencrypt/live/
Let's copy the .csr file also (most important!), assuming that this is the first certificate issued – take the one starting with
0000, otherwhise you can match the csr timestamp with the certificate you just generated:
cp /etc/letsencrypt/csr/0000_csr-certbot.pem /usr/local/etc/letsencrypt/live/mx.your.hostname/mx.your.hostname.csr
And lets modify the configuration file that we did before accordingly in order to tell certbot where the .csr file is, and where to place the certicate:
domains = mx.your.hostname webroot-path = /path/to/webserver/root csr = /usr/local/etc/letsencrypt/live/mx.your.hostname/mx.your.hostname.csr cert-path = /etc/letsencrypt/live/mx.your.hostname/cert.pem fullchain-path = /etc/letsencrypt/live/mx.your.hostname/fullchain.pem chain-path = /etc/letsencrypt/live/mx.your.hostname/chain.pem rsa-key-size = 4096 email = email@example.com text = True authenticator = webroot renew-by-default = true agree-tos = true
You can try reissuing the certificate with:
certbot -c /usr/share/etc/leconfig/mx.your.hostname certonly
Awesome! Your certificate should have been renewed with the same .csr file and private key. Now we can proceed to configuring postfix to use the certificate, private key and intermediate certificate. Look for the following lines:
smtpd_tls_key_file smtpd_tls_cert_file smtpd_tls_CAfile
And we will add the path to the certificate-chain:
smtpd_tls_key_file = /usr/local/etc/letsencrypt/live/mx.your.hostname/privkey.pem smtpd_tls_cert_file = /etc/letsencrypt/live/mx.your.hostname/cert.pem smtpd_tls_CAfile = /etc/letsencrypt/live/mx.your.hostname/chain.pem
Restart postfix, and you are ready for the next step!
Generate your own TLSA-record
We will use the “hash-slinger” package, and it is very simple! Just issue the following on any computer that has a https-connection to your mailserver:
tlsa --create mx.your.hostname
You will get something like this:
_443._tcp.mx.your.hostname. IN TLSA 3 0 1 54f3fd877632a41c15b0ff4e50e254ed8d1873486236dc6cd5e9c1c1993d1e4e
Perfect, you now has the record that you should deploy at your DNS-provider, with a slight modification:
_25._tcp.mx.your.hostname. IN TLSA 3 0 1 54f3fd877632a41c15b0ff4e50e254ed8d1873486236dc6cd5e9c1c1993d1e4e
Notice how we change the first part – the port. After you have published your record, wait for a little while and check if it valid with this tool.
Thank you for making Email awesome again!
I hope that you found this little guide helpful! Let me know what you think, hook me up on Mastodon on @firstname.lastname@example.org