Skip to main content
Back to Blog
Security

MTA-STS: Enforcing TLS for Email in Transit

How to implement MTA-STS to prevent email interception and downgrade attacks. Practical deployment guide with SMTP TLS Reporting.

Alex Kim
Author
December 22, 2025
10 min read

SMTP was designed in 1982-before encryption was a concern. Even with STARTTLS, opportunistic encryption can be stripped by attackers through downgrade attacks. MTA-STS (Mail Transfer Agent Strict Transport Security) solves this by publishing a policy that tells sending servers: "Always use TLS when delivering to this domain, and verify my certificate."

This guide covers practical MTA-STS implementation, including the companion SMTP TLS Reporting (TLS-RPT) standard that provides visibility into encryption failures.


The STARTTLS Problem

STARTTLS upgraded SMTP connections to encrypted TLS-a significant improvement over plaintext transmission. But it has a critical flaw: STARTTLS is opportunistic, not mandatory.

┌─────────────────────────────────────────────────────────────────────────┐
│                      STARTTLS DOWNGRADE ATTACK                           │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  NORMAL FLOW                                                             │
│  ───────────                                                             │
│  Sender ──────► Receiver                                                 │
│          EHLO                                                            │
│          ◄───── 250-STARTTLS                                             │
│          STARTTLS                                                        │
│          ◄───── 220 Ready                                                │
│          [TLS Handshake]                                                 │
│          🔒 Encrypted SMTP Session                                       │
│                                                                          │
│  ═══════════════════════════════════════════════════════════════════    │
│                                                                          │
│  ATTACK FLOW (MitM strips STARTTLS)                                      │
│  ──────────────────────────────────                                      │
│  Sender ──────► [Attacker] ──────► Receiver                              │
│          EHLO               EHLO                                         │
│          ◄───── 250 OK      ◄───── 250-STARTTLS                          │
│                 (no STARTTLS)       (stripped!)                          │
│          DATA                                                            │
│          ◄───── 354 Go ahead                                             │
│          📧 Plaintext email...                                           │
│          👁️ Attacker reads everything                                    │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

An attacker positioned between sender and receiver simply removes the STARTTLS advertisement. The sending server, seeing no STARTTLS support, transmits in plaintext. Neither party realizes the encryption was stripped.

MTA-STS prevents this by publishing policy out-of-band through HTTPS-a channel attackers can't silently manipulate.


How MTA-STS Works

MTA-STS uses two components:

  1. DNS TXT record: Signals policy existence and version
  2. Policy file: HTTPS-hosted file specifying enforcement mode

When a sending MTA prepares to deliver email, it:

  1. Checks for _mta-sts.example.com TXT record
  2. Fetches policy from https://mta-sts.example.com/.well-known/mta-sts.txt
  3. Caches the policy per its max_age directive
  4. Enforces TLS with certificate validation for subsequent deliveries
┌─────────────────────────────────────────────────────────────────────────┐
│                        MTA-STS VALIDATION FLOW                           │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  Sending MTA                              Receiving Domain               │
│  ───────────                              ────────────────               │
│       │                                                                  │
│       │  1. Check DNS TXT record                                         │
│       │─────────────────────────────────► _mta-sts.example.com           │
│       │◄───────────────────────────────── v=STSv1; id=20231215           │
│       │                                                                  │
│       │  2. Fetch policy via HTTPS                                       │
│       │─────────────────────────────────► mta-sts.example.com            │
│       │◄───────────────────────────────── /.well-known/mta-sts.txt       │
│       │                                                                  │
│       │  3. Cache policy (max_age)                                       │
│       │  [Policy stored locally]                                         │
│       │                                                                  │
│       │  4. Connect to MX with mandatory TLS                             │
│       │─────────────────────────────────► mail.example.com:25            │
│       │     STARTTLS (required)                                          │
│       │     Verify certificate matches *.example.com                     │
│       │     ✓ Deliver email encrypted                                    │
│       │     ✗ TLS failure → Reject (enforce mode)                        │
│       │                                                                  │
└─────────────────────────────────────────────────────────────────────────┘

Implementation Steps

Step 1: Verify Prerequisites

Before enabling MTA-STS, ensure your mail infrastructure supports it:

  • Valid TLS certificates: All MX hosts must have valid, trusted certificates
  • TLS 1.2 or higher: Older TLS versions should be disabled
  • Certificate hostname matching: Certs must match MX hostnames

Test your current configuration:

# Check MX records
dig MX example.com +short

# Test TLS on each MX
openssl s_client -connect mail.example.com:25 -starttls smtp

# Verify certificate validity
echo | openssl s_client -connect mail.example.com:25 -starttls smtp 2>/dev/null | openssl x509 -noout -dates

Step 2: Create the Policy File

Create a policy file at the well-known path. Start with testing mode:

version: STSv1
mode: testing
mx: mail.example.com
mx: mail2.example.com
max_age: 86400

Policy fields:

FieldValueDescription
versionSTSv1Protocol version (always STSv1)
modetesting/enforce/nonePolicy strictness
mxhostnamePermitted MX hostnames (one per line)
max_agesecondsCache duration (604800 = 1 week typical)

Mode options:

  • testing - Report failures but deliver anyway
  • enforce - Reject on TLS failure
  • none - Disable MTA-STS

Step 3: Host the Policy File

The policy must be served via HTTPS at: https://mta-sts.example.com/.well-known/mta-sts.txt

Using Cloudflare Pages:

  1. Create a new Pages project
  2. Add .well-known/mta-sts.txt with your policy content
  3. Set custom domain: mta-sts.example.com

Using AWS S3 + CloudFront:

# Create S3 bucket
aws s3 mb s3://mta-sts.example.com

# Upload policy
aws s3 cp mta-sts.txt s3://mta-sts.example.com/.well-known/mta-sts.txt \
    --content-type "text/plain"

# Configure CloudFront distribution with custom domain

Using GitHub Pages:

  1. Create repository mta-sts
  2. Add .well-known/mta-sts.txt
  3. Enable Pages with custom domain mta-sts.example.com

Critical requirements:

  • Valid HTTPS certificate (not self-signed)
  • Content-Type: text/plain
  • HTTPS only (HTTP must redirect or return error)

Step 4: Add DNS Records

Add the TXT record signaling MTA-STS availability:

_mta-sts.example.com. TXT "v=STSv1; id=20231215120000"

The id field is a version identifier. Update it whenever you change the policy-this signals senders to refresh their cached policy.

DNS configuration examples:

ProviderRecord TypeNameValue
CloudflareTXT_mta-stsv=STSv1; id=20231215120000
Route 53TXT_mta-sts.example.com"v=STSv1; id=20231215120000"
Google DomainsTXT_mta-stsv=STSv1; id=20231215120000

SMTP TLS Reporting (TLS-RPT)

TLS-RPT is the companion standard that provides visibility into TLS failures. Senders report connection problems-essential for identifying issues before enabling enforcement.

Configure TLS-RPT

Add a DNS TXT record requesting reports:

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

Report delivery options:

MethodFormatConfiguration
EmailJSON (gzipped)rua=mailto:reports@example.com
HTTPSJSON POSTrua=https://reports.example.com/tls

Understanding TLS Reports

Reports arrive as JSON, typically daily from major senders:

{
  "organization-name": "Google Inc.",
  "date-range": {
    "start-datetime": "2023-12-15T00:00:00Z",
    "end-datetime": "2023-12-15T23:59:59Z"
  },
  "policies": [
    {
      "policy": {
        "policy-type": "sts",
        "policy-domain": "example.com"
      },
      "summary": {
        "total-successful-session-count": 1523,
        "total-failure-session-count": 2
      },
      "failure-details": [
        {
          "result-type": "certificate-expired",
          "sending-mta-ip": "192.0.2.1",
          "failed-session-count": 2
        }
      ]
    }
  ]
}

Common failure types:

Result TypeCauseAction
starttls-not-supportedMX doesn't offer STARTTLSEnable STARTTLS
certificate-expiredTLS cert expiredRenew certificate
certificate-not-trustedCA not trustedUse trusted CA
certificate-host-mismatchHostname doesn't matchFix certificate SANs
validation-failureGeneral TLS failureCheck TLS config

Deployment Timeline

Week 1-2: Testing Mode

Deploy with mode: testing and monitor TLS-RPT:

version: STSv1
mode: testing
mx: mail.example.com
max_age: 86400

Review incoming reports. Common issues:

  • Legacy systems without STARTTLS
  • Certificate problems on backup MX
  • Misconfigured load balancers terminating TLS

Week 3-4: Fix Issues

Address any failures identified in reports:

  1. Certificate issues: Renew, replace with trusted CA, or fix SANs
  2. Missing STARTTLS: Update server configuration
  3. Load balancer problems: Ensure TLS passthrough or proper re-encryption

Week 5+: Enforce Mode

Once reports show consistent success, enable enforcement:

version: STSv1
mode: enforce
mx: mail.example.com
mx: mail-backup.example.com
max_age: 604800

Update the DNS TXT record id to trigger policy refresh:

_mta-sts.example.com. TXT "v=STSv1; id=20240115enforce"

Troubleshooting

Policy Not Detected

# Verify DNS record
dig TXT _mta-sts.example.com +short

# Verify policy is accessible
curl -I https://mta-sts.example.com/.well-known/mta-sts.txt

TLS Failures in Reports

# Test STARTTLS
openssl s_client -connect mail.example.com:25 -starttls smtp -servername mail.example.com

# Check certificate chain
openssl s_client -connect mail.example.com:25 -starttls smtp 2>/dev/null | openssl x509 -noout -text | grep -A1 "Subject Alternative Name"

MX Hostname Mismatch

Ensure the mx lines in your policy match your actual MX hostnames exactly. Wildcards aren't supported-list each MX explicitly.


MTA-STS for Major Providers

If you use hosted email, your provider may already support MTA-STS:

ProviderMTA-STS SupportConfiguration
Google WorkspaceBuilt-inAutomatic with domain verification
Microsoft 365Built-inEnabled via PowerShell
FastmailBuilt-inAutomatic
ZohoPartialManual policy required

For hosted providers, verify their MX hostnames and ensure your policy matches their infrastructure.


MTA-STS Best Practices

  1. Start in testing mode: Never go straight to enforce
  2. Monitor TLS-RPT: Reports reveal problems before they cause delivery failures
  3. Use reasonable max_age: 1 week (604800) balances caching with update flexibility
  4. Document all MX hosts: Missing an MX in policy causes failures
  5. Automate certificate renewal: Expired certs break enforcement
  6. Update id on changes: Senders cache aggressively-change id to force refresh

Complementary Standards

MTA-STS works alongside other email security standards:

StandardPurposeRelationship
SPF/DKIM/DMARCSender authenticationOrthogonal (authentication vs. encryption)
DANETLS via DNSSECAlternative approach (requires DNSSEC)
BIMIBrand logosRequires DMARC, complements MTA-STS

MTA-STS is generally easier to deploy than DANE (no DNSSEC dependency) and provides similar protection for the MX → receiver path.


Next Steps

MTA-STS protects email in transit-essential for any organization handling sensitive communications. Combined with DMARC for authentication and proper TLS configuration, you establish a comprehensive email security posture.

We help organizations implement complete email security stacks. Request an assessment to evaluate your current email infrastructure.


Questions about MTA-STS deployment for complex mail routing? We've handled multi-region setups, legacy gateway integrations, and hybrid Exchange environments. Contact us.

Tags:mta-stsemail-securitytlsencryptionsmtp

Want to Discuss This Topic?

Schedule a call with our team to discuss how these concepts apply to your organization.

30 Minutes

Quick, focused conversation

Video or Phone

Your preferred format

No Sales Pitch

Honest, practical advice

Schedule Strategy Call
Get Free Assessment