Configuring MTA-STS and SMTP TLS-RPT

MTA-STS (Mail Transfer Agent Strict Transport Security) is a new standard (defined in RFC8461) that aims to improve the security of SMTP by enabling domains to opt into a mode that requires authentication with valid public certificates and encryption (TLS). MTA-STS forces a TLS connection, preventing suppression of the STARTTLS upgrade, and defines what the MX records should be for a domain, therefore preventing DNS query interception to redirect to another MX record by a malicious party.

Much like HSTS makes TLS mandatory when using HTTP, MTA-STS makes encryption mandatory in SMTP.

While its use is not yet widespread among email providers, Gmail has become the first major email provider to support MTA-STS and TLS-RPT and the RFC was co-authored by several Googlers. Their adoption hopefully encourages other providers to follow suit soon. Read more in their blog post.

Deploying MTA-STS is relatively straight-forward once you understand the components involved. Here's an overview of what we'll cover:

Draft and publish the policy on a public, secured web server

Enable SMTP TLS-RPT via a TXT record

Signal MTA-STS support via a TXT record

First, make sure your MX records accept inbound TLS connections (according to Google's Transparency report, about 92% of servers currently do), they use TLS version 1.2 or later and the server TLS certificates:

Match the domain name used by the inbound mail server (the server in your MX records).

Are signed and trusted by a root certificate authority.

Are not expired.

Now, these last three go hand in hand, and are very likely already managed by your email host. You should only have to worry about them if you host your own mail server.

Then, we will proceed to draft the policy. The policy itself is pretty straight forward; here's a sample policy:

version: STSv1 mode: testing mx: aspmx.l.google.com mx: alt1.aspmx.l.google.com mx: alt2.aspmx.l.google.com mx: *.googlemail.com max_age: 604800

The important bits are mode, mx and max_age, as version will (for now) always be the same.

mode can be none , testing or enforce

none disables MTA-STS

testing tells external servers sending to you to evaluate the policy, requests reports (via TLS-RPT), but does not enforce connection security required by MTA-STS.

enforce tells external servers to verify they're connecting to an MX listed in the policy, and the SMTP connection is both encrypted (using TLS) and authenticated (that the server has a valid, signed certificate).

If the connection is not both encrypted and authenticated:

-- Servers that support MTA-STS will not send mail to your domain.

-- Servers that don't support MTA-STS continue to send messages to your domain over SMTP connections as they normally do, but they may not be encrypted.

Currently, the number of servers that support MTA-STS is low, and most email providers already use encrypted and authenticated connections, so this should not be a problem. However, I recommend keeping the policy in testing mode for at least a month. That way you can get familiar with MTA-STS and fix any issues that may be brought up by the STS reports.

mx lists the MX records that serve email for the domain. In almost all cases, it's the same records you already have published in your DNS.

To specify servers that match a naming pattern, use a wildcard. The wildcard character replaces one leftmost label only, for example: *.domain.com or *.mail.domain.com

max_age is the amount of time the sending MTA will cache the policy. The RFC suggests a value of 1 or 2 weeks (between 604800 and 1209600 seconds).

Ok, now that we have the policy drafted, we need to publish it. The policy has to be uploaded to a public-facing web server and it must be served over HTTPS with a signed, trusted certificate (eg: Let's Encrypt).

If you do not have a web server available to you, check out my guide on using GitHub Pages to host your MTA-STS policy.

Add a subdomain to your domain in the form of mta-sts.domain.com and point it to the web server

and point it to the web server Create a directory named .well-known in the subdomain.

in the subdomain. Upload the policy file you created to the .well-known directory with mta-sts.txt as the file name.

Your policy should be available at https://mta-sts.domain.com/.well-known/mta-sts.txt

Now is a good time to talk about the second topic of this post, before we continue with the last step of the deployment process.

SMTP TLS Reporting

How do we know that sending MTA's are failing MTA-STS? Much like DMARC, the answer is emailed reports. These reports include detected MTA-STS policies, traffic statistics, unsuccessful connections, and failure reasons. Enter SMTP TLS Reporting (or TLS-RPT for short). It enables reporting of TLS connectivity problems experienced by the sending MTA's and is defined in RFC8460.

Now, the last step consists on adding two DNS records: one for TLS-RPT and one to signify that you support MTA-STS and they're both simple TXT records.

Let's start with TLS-RPT. In order to receive TLS-RPT reports either create a mailbox where you will receive them, or sign up for a service like MailHardener or Report-URI which collects the reports for you and displays them in an easy to understand way.

The first TXT record should be added like this:

_smtp._tls.example.com. 300 IN TXT "v=TLSRPTv1; rua=mailto:tlsrpt@example.com"

Host: _smtp._tls

TTL: 900 (or your default value)

Value: v=TLSRPTv1; rua=mailto:tlsrpt@example.com

Note: You can also have reports submitted via POST to an API, using the endpoint as the rua. Eg: rua=https://reporting.example.com/v1/tlsrpt -- for more information, refer to the RFC

You may not get many reports, as not many MTAs are sending them (Google is the biggest that does, at the moment). However, as the standard gains traction, more MTAs will adopt TLS-RPT and DMARC analyzer services may opt to include TLS-RPT ingestion.

Lastly, we need to publicize our support for MTA-STS. The TXT record should be added as follows:

_mta-sts.example.com. 300 IN TXT "v=STSv1; id=1575556993"

Host: _mta-sts (note the underscore at the beginning)

TTL: 900 (or your default value)

Value: v=STSv1; id=1575556993

Update the id to a new value every time you change your MTA-STS policy. External servers use the id value to determine when your policy changes. I usually use the epoch time stamp for the id value, it's unique enough and lets you know when was the last time it was changed.

If you want to verify that both MTA-STS and TLS-RPT were setup correctly, run your domain through Hardenize. Their free domain report will analyze your policies and provide recommendations if they're not setup correctly. If you prefer a simpler tool that only validates MTA-STS and TLS-RPT you can use this one.

And that's it! You've enabled both MTA-STS and TLS-RPT, and you're on your way to supporting secure, un-tampered SMTP transmissions.

If you have any questions, feel free to reach out. I'm more than happy to help.