Under attack? Get incident response help

Email security

Publish MTA-STS and TLS-RPT in testing mode first

How to publish MTA-STS and TLS reporting for your domain, start in testing mode, read the reports and move to enforce without losing inbound mail.

Also in:TürkçeDeutschFrançaisEspañolItalianoPolskiNederlandsEesti

Illustration: Publish MTA-STS and TLS-RPT in testing mode first

SPF, DKIM and DMARC stop others forging your name (you can check your DMARC record), but none of them stops a sending server from delivering mail to you in plaintext. MTA-STS lets you publish a policy saying your mail servers support authenticated TLS, and TLS-RPT tells you when senders could not get it. You can deploy both with two DNS records and one text file, and you can start in a mode that is meant for soft deployment.

What STARTTLS leaves open

Server-to-server mail encryption uses the STARTTLS extension, and it is opportunistic. RFC 8461 describes the weak point: an attacker who can delete the "250 STARTTLS" response from the SMTP session, or redirect it by overwriting the resolved MX record, can force a downgrade or intercept the session.

DANE is the other fix, defined in RFC 7672, but it requires DNSSEC. MTA-STS relies on certification authorities instead and does not need DNSSEC, "at a cost of risking malicious downgrades" in the RFC's own words. If you already run DANE, the two do not conflict: senders implementing MTA-STS must not let it override a failing DANE validation.

The NCSC guidance on email security says your service should be capable of sending and receiving email using TLS, and that you should protect all your domains, including those at cloud providers such as Google G Suite and Microsoft O365.

Step one: the policy, in testing mode

MTA-STS has two parts. A TXT record at _mta-sts.example.com announces that a policy exists and which version it is:

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

The id is letters and digits, up to 32 characters, and must uniquely identify this version of the policy. There is no implied ordering, so a timestamp is a habit rather than a requirement. Publish exactly one such record: senders discard records not starting with v=STSv1;, and if the count is not one afterwards they assume you have no policy.

The policy itself is fetched over HTTPS from a fixed address, built by putting mta-sts in front of your domain:

https://mta-sts.example.com/.well-known/mta-sts.txt

Serve it as text/plain, because senders are told to check the media type. The file looks like this:

version: STSv1
mode: testing
mx: mail.example.com
mx: *.example.net
max_age: 604800

Each mx: line is its own entry, either a full hostname or a wildcard suffix such as *.example.net. List every host in your live MX records, including a cloud provider's.

The three modes are enforce, testing and none. The RFC describes testing as an optional mode that enables soft deployments to detect policy failures, which is why you start there.

The max_age is in seconds, up to 31557600, and 604800 (one week) is the RFC's own example. The RFC expects production values typically in the range of weeks or greater. My advice: keep it at a week or less while testing, so a corrected policy reaches senders quickly, and raise it once enforce has been stable.

Step two: turn on TLS-RPT

Detection only works if senders tell you what they saw. You publish a TXT record at _smtp._tls.example.com:

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

The rua can also be an https URI, in which case senders POST the report to it, and a comma-separated list is allowed. As with the MTA-STS record, exactly one TXT record must start with v=TLSRPTv1;, otherwise senders assume you do not implement it.

If you choose mailto, use a dedicated mailbox. Senders deliver these reports even when TLS fails, so a report may arrive unencrypted. Reports sent by email must carry a valid DKIM signature from the reporting domain, and the RFC says recipients must ignore those without one. Discard unsigned reports rather than acting on them.

Check what senders see

Query both records and fetch the policy file from outside your network:

dig TXT _mta-sts.example.com
dig TXT _smtp._tls.example.com
curl -si https://mta-sts.example.com/.well-known/mta-sts.txt

The dig output should show one record each, with the v= prefix first. The curl output should show a 200, Content-Type: text/plain and the policy body, so check that mode and every mx: line are what you intended. Fix any certificate error curl reports before you publish the TXT record.

Reading the reports

Reports are JSON files covering a time frame, with a delivery summary of success and failure counts. The RFC groups failures into negotiation, policy, general and transient failures. Reports may arrive compressed (the RFC defines application/tlsrpt+gzip), so unpack one first:

gzip -dc report.json.gz | jq .

The field names are defined in section 4.4 of RFC 8460. Read the summary counts first, then the failure entries.

A report with high success and no failures is what you want to see. The RFC notes that a report can act as a heartbeat showing TLS is negotiated as expected, and a steady run of clean reports is your evidence for moving on. Failures that name one of your own MX hosts point at a certificate or mx pattern you need to fix. One sender with a broken stack is their problem.

A jump in STARTTLS failures that you cannot tie to a change should go to whoever handles incidents, or to our incident response team if you have no one.

Moving to enforce

Wait until the reports are clean across your normal mail patterns, including quiet senders such as monthly invoicing systems. Then change mode: testing to mode: enforce and change the id in the TXT record, because senders compare it with their cached copy to learn that something changed.

Senders may cache a policy for up to max_age from the last fetch, so a mistake can linger. Deleting the TXT record does not remove a cached policy either, as the RFC points out. RFC 8461 section 8.3 covers removal, and you should read it before you need it.

Where to start

  1. List your live MX hosts, including any cloud provider's, and confirm each presents a valid certificate that matches its name.
  2. Set up the mta-sts host over HTTPS and serve the policy file as text/plain with mode: testing.
  3. Publish the single _mta-sts TXT record with a fresh id, then run the dig and curl checks above.
  4. Publish the _smtp._tls TXT record pointing to a dedicated mailbox or HTTPS endpoint, and check your overall setup with our email security checker.
  5. Review reports for at least one full business cycle, including month-end runs (for most organisations, a month). Fix every failure you own, then switch to enforce and change the id.

How we can help

Incident response

When something goes wrong, we contain it, find the root cause and help you recover.

Email security check

Grade a domain’s protection against spoofed email: SPF, DKIM, DMARC, DNSSEC, CAA and MTA-STS.

Contact us
AngelForce team

Written by the AngelForce team: security consultants with CEH, LPT Master and CISA certifications who test, monitor and defend systems for organisations across Europe.

Written with AI assistance from public sources listed below, and reviewed by the AngelForce team before publication.

Sources

  1. www.rfc-editor.org/rfc/rfc8461.html
  2. www.rfc-editor.org/rfc/rfc8460.html
  3. www.rfc-editor.org/rfc/rfc7672.html
  4. www.ncsc.gov.uk/collection/email-security-and-anti-spoofing

Articles about Email security

Tell us what you need to protect

Describe your environment and what you want to achieve. We will reply by email.

Contact us
info@angelforce.eu +372 5705 2044

AngelForce OÜ · Tallinn, Estonia