MTA-STS Is a Thing... Well Then (also feat. TLSRPT)

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 STARTTLS command. 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 TLSA record. 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, 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, mta-sts. 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: *

The version must be STSv1, the mode can either be enforce, testing, or none, the 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 MX records). Going back to the mode directive, 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). Either enforce or 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    IN    TXT    "v=STSv1; id=20210128000031Z"

The 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…

Configuring TLSRPT

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:    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 or https, with mailto then specifying an email address to send reports to, and https specifying an endpoint to POST a report to. Thus, rua= 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.

That’s it. 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, not email like with… email. So for a sending MTA, if you send TLSRPT reports, the DKIM key used must have a service field that allows for 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 l tag.