MTA-STS and TLS-RPT: making sure mail to you arrives encrypted

Why encryption between mail servers can be silently removed, how an MTA-STS policy and TLS reports prevent and reveal it, and how to set both up in an afternoon.

6 min read

When a server sends an e-mail to your domain, it looks up your MX records and connects to your mail server. It then asks “can we encrypt?” with a command called STARTTLS, and if your server says yes, the rest of the conversation is encrypted. The weakness is in that question. Anyone in a position to tamper with the connection can remove your server’s “yes”, and most sending servers will then deliver the message in clear text rather than not at all. The same attacker can also answer with a forged certificate, and most senders accept it.

MTA-STS (RFC 8461) closes that gap. TLS-RPT (RFC 8460) tells you when something goes wrong.

How MTA-STS works

You publish, over HTTPS, a short policy file that says: “mail for this domain must be delivered over TLS, with a valid certificate, to these servers”. Sending servers that support MTA-STS (Gmail, Outlook.com and Microsoft 365 among them) fetch it, cache it, and refuse to deliver if they cannot meet it. Since the policy comes from an HTTPS site with a valid certificate, an attacker on the network path cannot fake it.

It takes three things.

1. The policy file, served at exactly this address:

https://mta-sts.yourdomain.com/.well-known/mta-sts.txt

with this content:

version: STSv1
mode: testing
mx: yourdomain-com.mail.protection.outlook.com
max_age: 604800

mx lists your mail servers (one line each, wildcards such as *.mail.protection.outlook.com allowed). max_age is how long senders may cache the policy, in seconds; a week is a sensible start.

2. A host for it. The mta-sts subdomain needs a valid certificate. Any static hosting works: a small page on your existing web host, GitHub Pages, Cloudflare Pages or a Worker.

3. A DNS record announcing the policy:

_mta-sts.yourdomain.com.  TXT  "v=STSv1; id=20261112"

Change id whenever you change the policy file, so senders fetch the new version.

Start in testing, then enforce

In mode: testing, senders deliver as before but report failures to you. Leave it for two to four weeks while you read the reports, then switch to mode: enforce and change the id. In enforce mode, a sender that cannot get a valid encrypted connection to a listed server keeps the message in its queue and retries rather than delivering it in clear.

TLS-RPT: the reports

One DNS record:

_smtp._tls.yourdomain.com.  TXT  "v=TLSRPTv1; rua=mailto:tls-reports@yourdomain.com"

Senders such as Google and Microsoft then send you a daily JSON report: how many connections to your servers succeeded with TLS, and the failures with their reason (expired certificate, name mismatch, policy not found, STARTTLS not offered). Without these reports, an expired certificate on your mail server could stop delivery for days before anyone notices.

Common mistakes

  • The mx lines do not match the real MX records. In enforce mode, mail stops. Check them against dig MX yourdomain.com every time you change mail provider.
  • The policy site’s certificate expires. Senders that already cached the policy keep it until max_age; new ones cannot fetch it. Use automatic renewal.
  • Forgetting the id. Senders keep the old policy until it expires.
  • Going straight to enforce without reading a single report.

Where DANE fits

DANE does the same job using DNSSEC instead of HTTPS: your MX servers’ certificates are pinned in signed DNS records. It is widely used in Germany and the Netherlands, and Microsoft supports it in Exchange Online. If your DNS is signed, DANE and MTA-STS can live side by side (see DNSSEC and CAA).

How Perimetry checks it

Every audit fetches your MTA-STS policy, checks that it parses, that the mode is set, that the mx lines cover your real MX records and that the site’s certificate is valid, and reads your TLS-RPT record. Perimetry Cloud can also receive your TLS reports itself and show, day by day, whether mail to you arrived encrypted. The free DNS record generator writes the policy file and both records for you.

To check a domain, the free MTA-STS and TLS-RPT checker reads the record, fetches the policy file as a sender would and compares it with your MX hosts.