If you’re just curious, MTA-STS relates to SMTP, in the same way that HSTS relates to HTTP. Except, naturally, it relies on, you get three guesses… yes, DNS. And this is what it is, and how to set it up.
Officially documented in RFC 8461, MTA-STS allows for a MTA (mail server) to publish a policy where, if the sending side respects it, will know to only use TLS encryption for mail sent to said MTA.
See, as much as we would like for email to be a 100% secure system, it’s not.
And all the RFCs have spoken — You cannot require TLS, you have to accept plaintext delivery, meaning, you have to accept delivery on a plaintext port (so, not 465) that did not include a
The best we can do, however, is for conforming sending MTAs, tell them that we would prefer they use TLS wherever possible, and to refuse to send mail if they cannot.
A way this has been done for a while is DANE, or DNS Based Authentication of Named Entities, which uses a special record called a
TLSA record, to hold, in the most common case, a hash of your TLS certificate.
Postfix has had support for DANE for a while, if you tell it to, it will attempt to fetch a domain’s
TLSA records before sending to it, verify that they’re signed with DNSSEC, and then refuse delivery if they cannot negotiate TLS, or the TLS certificate presented doesn’t match the data in the
This does require a few things though, namely… DNSSEC, and recomputing hashes every time your certificates rotate, which if you’re like me, and use Let’s Encrypt, that’s every 90 days.
MTA-STS attempts to provide something similar, by publishing a policy to tell sending MTAs to only deliver to you with TLS.
The first part is to create the policy file, which, for the domain
example.com, much be able to reached at the following URL:
Note that the protocol there is HTTPS.
This is required.
You need a valid TLS certificate on your web server to allow for enforcing TLS on your mail server.
Also, note the subdomain,
This is, again, required.
A MTA-STS policy file is a text file containing one directive per line, like so:
version: STSv1 mode: testing max_age: 86400 mx: mail.example.com mx: *.example.net
version must be
mode can either be
max_age is the age, in seconds, that clients are allowed to cache the policy for, and then each
mx lists a domain name that is a valid MX
for this domain (in other words, list all the values of your
Going back to the
enforce is the only one that will actually cause messages to not be delivered if the policy cannot validate (meaning, no matching listed MX has good TLS).
testing will send TLSRPT reports (more on that later), and
none causes the policy to be discarded, meaning sending MTAs are to act as if no MTA-STS policy exists.
Also of note: HTTP redirects and caching are not respected.
A request for your policy must be a
200 OK response, or it will fail to be fetched.
After this, you need a single DNS record, again, using an example domain of
_mta-sts.example.com IN TXT "v=STSv1; id=20210128000031Z"
v tag is always
STSv1, and the
id is an alphanumeric string, that identifies a particular policy version.
It’s value has no value, but if the
id changes between fetches, the policy has changed too, and should be re-fetched, ignoring cache.
In other words, set this to anything you want, and make sure to change it to something different every time you edit that policy file.
Using a timestamp or the first few characters of the file’s hash would work just fine.
With these two deployed, in theory, you should be good. Not many MTAs right now support MTA-STS, but Google does, and given how large they are, that means that the majority of email received should likely be guaranteed to be TLS.
But if you want to go one step beyond though…
TLSRPT (SMTP TLS Reporting), defined in RFC 8460, is a standard for sending MTAs to report TLS connectivity issues to receiving MTAs, and works hand-in-hand with MTA-STS. It’s effectively the DMARC for SMTP TLS. And unlike MTA-STS, and like DMARC, all you need is a single DNS record, using our ever-beloved example domain:
_smtp._tls.example.com IN TXT "v=TLSRPTv1; rua=mailto:[email protected]"
As with all these, the
v tag has a fixed value.
And in this case, there’s only one other tag,
rua, which can contain a comma-separated list of URIs to send reports to.
They can either be
mailto then specifying an email address to send reports to, and
https specifying an endpoint to POST a report to.
rua=https://reporting.example.com/tlsrpt is perfectly valid.
When reporting, TLS errors are ignored, meaning for
https reports, the certificate does not need to be valid, and for
mailto reports, MTA-STS and DANE
TLSAs are not enforced, and not included in the next report.
From there, just make sure that whatever you specified in the
rua is ready to handle the JSON formatted reports that may be sent to it.
Reports are generally generated covering a one-day period, but since the adoption rate of MTA-STS and TLSRPT seems pretty low, chances are only the big ones (again, like Google, which has publicly declared their support) will send you anything.
mailto reporting DKIM records
There is one small footnote to this:
When sending a message to a
mailto report URI, the DKIM service name (
s) used is
tlsrpt, or, more likely, has no service field, thus not restricting it’s usage.
Additionally, a DKIM signature is not allowed to limit the signed body length with the