MTA-STS And TLS Reporting, In Plain Terms
The Mythic Intel Team · Aug 19, 2025 · 7 min read
MTA-STS, defined in RFC 8461, lets a receiving domain tell sending servers that mail to it must be delivered over authenticated TLS, closing the gap that lets an active attacker strip STARTTLS and read mail in the clear. TLS-RPT, defined in RFC 8460, is the companion: it publishes a DNS record asking senders to mail you daily reports about whether their TLS connections to you succeeded or failed. Together they turn opportunistic, silently-downgradeable SMTP encryption into a policy you can enforce and a failure mode you can actually see.
The problem both solve is that STARTTLS is opportunistic by default. A sending MTA offers STARTTLS, the receiver advertises it, they negotiate TLS, and if anything goes wrong the sender falls back to plaintext rather than failing. A man-in-the-middle can strip the STARTTLS advertisement from the receiver's banner and the sender will happily send in clear text, with no warning to either side. MTA-STS removes the silent fallback for domains that opt in.
How an MTA-STS policy is published
MTA-STS uses two coordinated pieces: a small DNS TXT record that signals a policy exists and carries a version id, and the policy itself served over HTTPS from a fixed well-known path. Splitting it this way means the policy is fetched over an authenticated, certificate-validated HTTPS channel rather than trusting DNS alone.
The TXT record lives at _mta-sts under the domain:
_mta-sts.example.com. IN TXT "v=STSv1; id=20240615T120000Z"
The id is an opaque string that changes whenever you update the policy. A sender that has the policy cached compares the cached id against this record and refetches only when it changes, so this lookup is cheap and the policy itself is fetched rarely.
The policy file is served from a host named mta-sts.<domain> at the exact path /.well-known/mta-sts.txt, over HTTPS with a valid certificate for that hostname:
https://mta-sts.example.com/.well-known/mta-sts.txt
version: STSv1
mode: enforce
mx: mail.example.com
mx: *.mx.example.com
max_age: 604800
The fields:
version: STSv1is mandatory and fixed.modeis the enforcement level.nonemeans there is no active policy (used to back out cleanly),testingmeans apply the rules but deliver anyway and rely on TLS-RPT to report failures, andenforcemeans refuse to deliver to any MX that does not match the policy and present a valid certificate.mxlists the allowed MX hostnames. A single*wildcard is permitted as the leftmost label only, so*.mx.example.commatches one level. Every MX in your DNS must be covered by anmxline or enforce mode will block legitimate delivery to it.max_ageis how long, in seconds, a sender may cache this policy. Common values run from a day up to the spec maximum of 31557600 seconds (about a year). A longmax_ageis a feature: a cached enforce policy keeps protecting you even if an attacker manages to tamper with your DNS, because the sender keeps honoring the cached version.
How a sender enforces it
When an MTA at a sending domain has mail for example.com, the MTA-STS-aware path is:
- Resolve MX records for
example.comas usual. - Look up
_mta-sts.example.comTXT. If present, and theiddiffers from any cached policy, fetchhttps://mta-sts.example.com/.well-known/mta-sts.txtover HTTPS, validating the certificate formta-sts.example.com. - For the chosen MX host, check that it matches one of the
mxpatterns in the policy and that, on connection, it negotiates TLS and presents a certificate that is valid and matches the MX hostname. - If
mode: enforceand either the MX is not listed or TLS validation fails, do not deliver. The message is deferred (a transient failure), not bounced, so the sender retries in case the failure was an attack or a transient misconfiguration. Ifmode: testing, deliver anyway and emit a TLS-RPT report.
The deferral on failure is the safety valve. A botched policy update does not instantly bounce mail; it queues it, which gives you a window to notice and fix.
TLS-RPT: seeing the failures you would otherwise miss
The hard part of MTA-STS in production is that a misconfigured policy fails silently from your side, since the failing sender is someone else's MTA. TLS-RPT fixes that by asking senders to report. Publish a TXT record at _smtp._tls:
_smtp._tls.example.com. IN TXT "v=TLSRPTv1; rua=mailto:[email protected]"
rua is the reporting address, and it also accepts an HTTPS endpoint (rua=https://...) for posting reports. Senders that support TLS-RPT then send a daily aggregate report, formatted as I-JSON per RFC 7493, summarizing their connection attempts. A report records, per policy applied, the count of successful TLS sessions and the count and type of failures, covering DNS resolution problems, STARTTLS negotiation failures, and policy validation errors for both MTA-STS and DANE.
A failure entry in a report looks like:
{
"policy": {
"policy-type": "sts",
"policy-domain": "example.com"
},
"summary": {
"total-successful-session-count": 9871,
"total-failure-session-count": 14
},
"failure-details": [
{
"result-type": "certificate-expired",
"sending-mta-ip": "203.0.113.9",
"receiving-mx-hostname": "mail.example.com",
"failed-session-count": 14
}
]
}
That single block tells you 14 sessions failed because your MX certificate expired, which is the kind of problem that is invisible without reporting and catastrophic under mode: enforce. The standard practice is to publish TLS-RPT first, then MTA-STS in mode: testing, watch the reports for a couple of weeks to confirm zero unexpected failures, and only then move to mode: enforce.
Saying it out loud
In an interview: "STARTTLS is opportunistic and silently downgradeable, so MTA-STS, RFC 8461, lets the receiver publish a policy, a TXT at _mta-sts pointing to an HTTPS-served file at mta-sts.<domain>/.well-known/mta-sts.txt, that says enforce TLS to these MX hosts with valid certs or do not deliver. Senders cache it by max_age, which also hardens it against DNS tampering. TLS-RPT, RFC 8460, is the feedback loop: a TXT at _smtp._tls collects daily JSON reports of TLS successes and failures, so I roll out TLS-RPT first, then MTA-STS in testing, then enforce once the reports are clean." That sequence shows you understand both the threat model and the operational discipline of not enforcing blind.