What is MTA-STS (MTA Strict Transport Security)?
MTA-STS is a mechanism that enforces TLS encryption for your email communication. Think of it as HTTP Strict Transport Security (HSTS) for email. By instructing the sending mail server that a secure connection is mandatory, you can effectively mitigate or stop Man-in-the-Middle (MITM) attacks. The official abstract from the RFC puts it best:
SMTP MTA Strict Transport Security (MTA-STS) is a mechanism enabling mail service providers (SPs) to declare their ability to receive Transport Layer Security (TLS) secure SMTP connections and to specify whether sending SMTP servers should refuse to deliver to MX hosts that do not offer TLS with a trusted server certificate.
SMTP MTA Strict Transport Security (MTA-STS). RFC 8461. https://www.rfc-editor.org/rfc/rfc8461.html
In scenarios where DNSSEC isn’t an option, MTA-STS serves as a strong alternative to DANE. However, it’s crucial to understand that without DNSSEC, MTA-STS remains susceptible to downgrade attacks via DNS spoofing. It’s a trade-off worth considering.
What is TLSRPT (TLS Reporting)?
TLSRPT adds a crucial reporting layer to SMTP TLS connections. It’s a standardized way for sending mail servers to report on TLS connection failures, including details about which DANE or MTA-STS policy was in effect. The RFC clearly outlines its purpose:
A number of protocols exist for establishing encrypted channels between SMTP [..]. These protocols can fail due to misconfiguration or active attack, leading to undelivered messages or delivery over unencrypted or unauthenticated channels. This document describes a reporting mechanism and format by which sending systems can share statistics and specific information about potential failures with recipient domains. [..]
SMTP MTA TLS Reporting (TLSRPT). RFC 8460. https://www.rfc-editor.org/rfc/rfc8460.html
This reporting is invaluable for observability and troubleshooting, allowing you to catch misconfigurations before they cause major issues.
Requirements
Setting up MTA-STS and TLSRPT requires a few key components:
- SSL Certificate: Unlike with DANE, your certificate must be issued by a trusted Certificate Authority. A self-signed certificate won’t work.
- Webserver: You need a web server to publish the MTA-STS policy file.
- DNS Control: The ability to add specific DNS records (TXT, A, AAAA) for your mail domains is mandatory.
- Minimum TLS Version: Your Mail Transfer Agent (MTA) must support at least TLS 1.2.
Hands-on Setup: DNS Records
The first step is configuring the necessary DNS records. It’s important to note that you must add an MTA-STS record for every domain you send mail from, including subdomains. As RFC 8461 specifies, “the policy can be fetched only from ‘mail.example.com’, not ‘example.com’.”
_mta-sts TXT record
This record contains two fields: a version (v=STSv1) and a unique identifier (id=). The id acts like a serial number. Every time you update the policy file, you must change the id value to signal senders that a new policy is available.
Here’s how I manage this using nsupdate with Bind 9.16:
root@ns3:~# nsupdate -l
> zone jeanbruenn.info
> update add _mta-sts.jeanbruenn.info. 3600 IN TXT "v=STSv1; id=202107300200Z"
> sendTo simplify administration across multiple domains, I prefer using CNAMEs to point all _mta-sts records to a central domain. This adheres to the “Once and Only Once” (OAOO) principle, which is a core concept of Infrastructure as Code (IaC). It ensures consistency and simplifies future administration. My main mailing domain is no-uce.de, so the process looks like this:
root@ns3:~# nsupdate -l
> zone no-uce.de
> update add _mta-sts.no-uce.de. 3600 IN TXT "v=STSv1; id=202107300200Z"
> send
> # for every domain point it to the mailservers domain
> zone jeanbruenn.info
> update add _mta-sts.jeanbruenn.info. 3600 IN CNAME _mta-sts.no-uce.de
> sendmta-sts A/AAAA record
Since the policy must be served over HTTPS, a DNS record is required to point the hostname to your web server. In my case, I want to centralize the policy on one system with the IP 1.2.3.4:
root@ns3:~# nsupdate -l
> zone no-uce.de
> update add mta-sts.no-uce.de 3600 IN A 1.2.3.4
> sendAnd again, I use CNAMEs to point other domains to this central policy server.
root@ns3:~# nsupdate -l
> zone jeanbruenn.info
> update add mta-sts.jeanbruenn.info. 3600 CNAME mta-sts.no-uce.de
> send_smtp._tls TXT record
This record tells other systems where to send TLS reports. While the RFC doesn’t explicitly state whether CNAMEs should be followed, I use them for simplicity. This way, if I ever change the reporting address, I only have to update it in one place.
root@ns3:~# nsupdate -l
> zone no-uce.de
> update add _smtp._tls.no-uce.de 3600 IN TXT "v=TLSRPTv1; rua=mailto:himself@jeanbruenn.info"
> zone jeanbruenn.info
> update add _smtp._tls.jeanbruenn.info 3600 CNAME _smtp._tls.no-uce.de
> sendConfiguring the Webserver & Policy
Next, we configure the web server to host the policy file. According to the RFC, your server must be able to respond to requests for mta-sts.yourdomain.com with a valid SSL certificate that covers all policy domains.
NGINX Configuration
It’s often practical to set up the server block without SSL first to obtain your Let’s Encrypt certificates. The key is to ensure the server_name directive includes all of your MTA-STS hostnames.
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/letsencrypt/live/mta-sts.no-uce.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mta-sts.no-uce.de/privkey.pem;
root /var/www/mta-sts;
index index.html index.htm index.nginx-debian.html;
server_name mta-sts.no-uce.de
mta-sts.jeanbruenn.info;
location / {
try_files $uri $uri/ =404;
}
}The Policy File
The policy is a simple text file located at /.well-known/mta-sts.txt.
root@mail:/var/www/mta-sts/.well-known# cat mta-sts.txt
version: STSv1
mode: enforce
max_age: 2419200
mx: mail.no-uce.deThe mode can be set to testing to get reports without enforcing the policy, or enforce to fully activate it. I use 28 days for max_age, which is specified in seconds.
The Second Half: Verifying Incoming Mail
Setting up the public-facing policy is only half the battle. The second, more complex part is configuring your MTA to verify the policies of incoming mail.
I chose the postfix-mta-sts-resolver for Postfix, which does exactly this. It’s a promising solution, but a key point to remember is that it may override DANE if you have both configured.
First, install the necessary dependencies:
apt-get install python3-pip
python3 -m pip install postfix-mta-sts-resolverNext, configure your Postfix main.cf to use the resolver:
smtp_tls_policy_maps = socketmap:inet:127.0.0.1:8461:postfixMy mta-sts-daemon.yml configuration is straightforward:
root@mail:/etc/systemd/system# cat /etc/mta-sts-daemon.yml
host: 127.0.0.1
port: 8461
reuse_port: true
shutdown_timeout: 20
cache:
type: internal
options:
cache_size: 10000
proactive_policy_fetching:
enabled: true
default_zone:
strict_testing: false
timeout: 4Validation and Conclusion: The Infrastructure as Code Approach
To verify your setup, you can use a public validator; there are several available. I also monitor TLS reports to ensure everything is working as expected.
A report I received by google while I was testing and playing around with MTA-STS and TLSRPT:
{
"organization-name":"Google Inc.",
"date-range":
{
"start-datetime":"2021-07-29T00:00:00Z",
"end-datetime":"2021-07-29T23:59:59Z"
},
"contact-info":"smtp-tls-reporting@google.com",
"report-id":"2021-07-29T00:00:00Z_no-uce.de",
"policies":[
{
"policy":
{
"policy-type":"no-policy-found",
"policy-domain":"no-uce.de"
},
"summary":
{
"total-successful-session-count":7,
"total-failure-session-count":0
}
}]
} Who uses MTA-STS?
I even wrote a simple script to check which mail providers sending mails to my system use MTA-STS:
while read -r domain; do
echo $domain;
mtasts=$(dig TXT _mta-sts.$domain +short);
if [ ! -z "$mtasts" ]; then
echo $mtasts;
curl -s "https://mta-sts.$domain/.well-known/mta-sts.txt";
fi
dig TXT _smtp._tls.$domain +short;
echo "";
done< <(grep -E "qmgr.*from=<" /var/log/mail.info | sed -r 's_.*from=<(.*)@(.*)>,? .*_\2_' | sort -u | grep -v queue)My quick findings show that many major players, including Facebook, Gmail, and Hotmail, are using these technologies to secure their email traffic.
It’s clear that while setting up MTA-STS and TLSRPT requires multiple steps, the result is a significant boost to your mail security and a valuable tool for monitoring its health.
See also
- IETF DANE Working Group. The IETF’s official working group on DNS-based Authentication of Named Entities (DANE) and TLS. (https://datatracker.ietf.org/wg/dane/)
- RFC 8461. SMTP MTA Strict Transport Security (MTA-STS). (https://www.rfc-editor.org/rfc/rfc8461.html)
- RFC 8460. SMTP MTA TLS Reporting (TLSRPT). (https://www.rfc-editor.org/rfc/rfc8460.html)
- Google Online Security Blog. Protecting email in transit with MTA-STS. (https://security.googleblog.com/2018/10/protecting-email-in-transit-with-mta-sts.html)
- Red Hat. Configuring MTA-STS with Postfix. (https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/configuring_and_managing_postfix/configuring-mta-sts-with-postfix)
- Cloudflare Blog. Making Email Safer with MTA-STS and TLS-RPT. (https://blog.cloudflare.com/making-email-safer-with-mta-sts-and-tls-rpt/)
- GitHub. postfix-mta-sts-resolver. (https://github.com/Snawoot/postfix-mta-sts-resolver)
Hi Jean,
I’m interested in the third part 😉 – which is sadly missing:
The implementation of TLS reporting with Postfix.
It seems to be not easy possible, if at all…
Hey Christoph,
give me a few days I’ll check. I’m also curious about that one. If I find something for that I’ll let you know 🙂
Jean