MTA-STS: How to Force Other Servers to Encrypt the Mail They Send You - init.d - sistemistica Linux, DevOps e sviluppo PrestaShop

# MTA-STS: How to Force Other Servers to Encrypt the Mail They Send You

Alessandro Corbelli~6 min
Table of Contents

In the article on STARTTLS stripping we left one problem open: between one mail server and another (port 25) implicit TLS is not practical, and encryption stays opportunistic. The sending server tries to encrypt "if available"; someone in the middle can make it look unavailable.

MTA-STS (Mail Transfer Agent Strict Transport Security, RFC 8461) is the answer that does not require DNSSEC. The owner of a domain publishes a rule that tells the servers writing to it: "use TLS, to these specific servers, with a valid certificate. Otherwise do not deliver." You need a DNS record and a file on an HTTPS site.

An analogy: it is the notice on the door of an apartment building. "Parcels are handed only to the doorman, inside, with ID." A courier who has read it never leaves a parcel with a stranger on the pavement.

How it works

MTA-STS has two parts.

1. A DNS TXT record that signals a policy exists:

_mta-sts.example.com. IN TXT "v=STSv1; id=20261101000000Z;"

The id changes with every policy change: senders use it to know they must download the policy again. Microsoft suggests, for example, using the UTC date and time.

2. A policy file served over HTTPS at a fixed address, on the mta-sts subdomain:

https://mta-sts.example.com/.well-known/mta-sts.txt
version: STSv1
mode: enforce
mx: mail.example.com
mx: backup-mx.example.com
max_age: 1209600
  • mx: the mail servers allowed to receive for the domain (a wildcard is allowed only on the left, such as *.example.net). An MX record pointing to an unlisted host fails validation.
  • mode: testing (if the check fails, mail may still be delivered, and senders that support TLS-RPT send a report), enforce (if the check fails, do not deliver) or none.
  • max_age: for how many seconds the policy may stay cached at the sender, up to 31557600 (about a year). The RFC recommends values in the range of weeks or more.

In enforce mode, the RFC forbids the sender from delivering to a server that is not in the mx list, does not support STARTTLS or presents an invalid certificate. The certificate must be unexpired, chain to a trusted CA and have a name matching the MX host. These failures must be treated as transient: the message is retried later.

A real example

The gmail.com domain publishes MTA-STS. Querying DNS and the site (checked on 1 November 2026):

Terminal window
dig +short TXT _mta-sts.gmail.com
curl -sS https://mta-sts.gmail.com/.well-known/mta-sts.txt
"v=STSv1; id=20190429T010101;"
version: STSv1
mode: enforce
mx: smtp.google.com
mx: gmail-smtp-in.l.google.com
mx: *.gmail-smtp-in.l.google.com
max_age: 86400

It also publishes a reporting record: _smtp._tls.gmail.com contains "v=TLSRPTv1;rua=mailto:sts-reports@google.com".

Reports: TLS-RPT

MTA-STS alone works blind: if a certificate expires, senders stop delivering and you do not know. That is why it is paired with TLS-RPT (RFC 8460), a DNS record saying where to send summaries of connection outcomes:

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

According to RFC 8460 reports are in JSON format (gzip compression is recommended) and normally cover a full day, 00:00 to 24:00 UTC. Among the errors they report are starttls-not-supported, certificate-expired, certificate-host-mismatch, certificate-not-trusted and, for MTA-STS, sts-policy-fetch-error, sts-policy-invalid and sts-webpki-invalid. It is the same logic as the DMARC reports described in SPF, DKIM and DMARC: first observe, then enforce.

How to publish it, step by step

  1. A valid certificate for mta-sts.example.com and an HTTPS site that serves it.
  2. The policy file, in mode: testing.
  3. The two DNS records: _mta-sts and _smtp._tls.
  4. An observation period while reading the reports. Google's instructions for Gmail suggest starting in testing for about two weeks.
  5. Switch to enforce: edit the file and change the id in the DNS record, otherwise senders keep using the cached policy until max_age expires.

The file can be served by any web server, as long as it answers at that address with the right certificate. The RFC is precise on two details: only an HTTP 200 response is valid, and 3xx redirects are not followed. A 301 to another address is the same as not having a policy. The expected content type is text/plain.

What can go wrong

  • Invalid mail server certificate with enforce on. Senders do not deliver. Exchange Online, for example, returns to the sender a 5.7.5 error ("Remote certificate failed MTA-STS validation") when the destination server's certificate is not valid. With certificates getting shorter, down to 47 days, automatic renewal is no longer optional.
  • An MX not listed in the policy. Exchange Online returns 5.4.8 ("MX hosts failed MTA-STS validation") when the MX host is not the one expected by the policy.
  • id not updated after a change: senders use the old policy until max_age expires.
  • Wildcards that are too broad in the mx lines: the RFC warns that they weaken the check.

The limits of MTA-STS

RFC 8461 is explicit: MTA-STS protects a domain only if the sender was previously able to obtain and keep the policy. Whoever can block DNS at first contact can stop the sender from learning it and cause the downgrade. The RFC observes that DANE avoids this problem, because DNSSEC can authoritatively prove that a record does not exist.

MTA-STS also only protects senders that implement it, and only mail arriving at your domain. For outbound mail, your server must check other people's policies: for Postfix there is an external component, postfix-mta-sts-resolver, a daemon that gives Postfix TLS policy based on the recipient domain's MTA-STS policy.

Among large providers, Exchange Online validates with MTA-STS all messages sent to MTA-STS-protected recipients, with no configuration needed, and Google documents support in Gmail and Google Workspace (outbound messages to servers with an enforce-mode policy, and a policy you can publish for your own domain).

How to verify

Terminal window
dig +short TXT _mta-sts.example.com
dig +short TXT _smtp._tls.example.com
curl -sS -i https://mta-sts.example.com/.well-known/mta-sts.txt
openssl s_client -starttls smtp -connect mail.example.com:25 -servername mail.example.com -brief

The last command shows the certificate presented by the MX: it must be valid and the name must match one of the policy's mx lines.

In short

MTA-STS makes encryption of inbound mail mandatory for whoever asks for it: a DNS record, a file over HTTPS, a valid certificate on the MX servers. You start from testing, read the TLS-RPT reports and only then move to enforce. The risk is certificate management; the limit is trust on first connection.

Sources

Tux versione Gandalf, mascotte del blog init.d

init.d is the team led by Alessandro Corbelli, a Linux systems administrator and backend developer with over twenty years of experience. He designs and runs cloud infrastructure (Google Cloud, AWS, Azure), server farms and high-availability architectures, and builds custom software in Laravel/PHP and Vue - from the Take2Me food delivery platform to our clients' management tools. On this blog we share technical notes on Linux, system administration, development, DevOps and e-commerce.


More Posts