Back to tutorials
Tutorial

Postfix MTA-STS Setup Guide Tutorial (2026): Enforce TLS for Your VPS Email Domain with DNS + Nginx

Postfix MTA-STS setup guide tutorial (2026) to enforce TLS for inbound mail using DNS + an HTTPS policy host on your VPS.

By Anurag Singh
Updated on Oct 06, 2026
Category: Tutorial
Share article
Postfix MTA-STS Setup Guide Tutorial (2026): Enforce TLS for Your VPS Email Domain with DNS + Nginx

SMTP is still “best effort” by default. If a sender can’t negotiate TLS, many MTAs quietly fall back to plaintext. In 2026, you don’t have to accept that behavior for your domain. This Postfix MTA-STS setup guide tutorial shows how to publish an MTA-STS policy over HTTPS and enable TLS reporting. With that in place, major senders (Google, Microsoft, Yahoo, and most serious MTAs) won’t deliver to your domain unless they can use TLS to your MX hosts.

You’ll do three things:

  • Confirm your MX hosts support STARTTLS with a valid certificate.
  • Publish a small policy file at mta-sts.yourdomain.
  • Add two DNS TXT records.

The payoff is simple: fewer downgrade attacks, clearer failure signals, and fewer “it delivered but wasn’t encrypted” blind spots.

What you’ll build (and why MTA-STS matters for a hosting VPS)

MTA-STS (SMTP MTA Strict Transport Security) lets your domain tell senders: “Only deliver to my MX hosts if you can negotiate TLS with a valid certificate.” Senders enforce it, not Postfix.

That’s why the work lives in DNS plus an HTTPS-hosted policy file.

  • Protects against STARTTLS stripping and downgrade attacks between sending and receiving MTAs.
  • Hardens multi-tenant email on a VPS where you host mail for business domains or reseller customers.
  • Improves troubleshooting: TLS-RPT reports tell you who failed to deliver and why (expired cert, wrong MX, no TLS, etc.).

If you run your own mail stack on a VPS, start from a setup you can control end-to-end. That means rDNS, firewall rules, and certificates. A clean option is a HostMyCode VPS.

Prerequisites checklist (don’t skip these)

  • A domain you control (example: example.com).
  • MX records already pointing to your mail hostnames (example: mx1.example.com).
  • Inbound SMTP reachable on TCP/25 to your MX server(s).
  • STARTTLS enabled on inbound SMTP (usually Postfix on 25).
  • A valid certificate for the MX hostname(s) used by inbound SMTP.
  • An HTTPS vhost you can serve at https://mta-sts.example.com/.well-known/mta-sts.txt.

If deliverability is already messy, fix the fundamentals first. That includes SPF/DKIM/DMARC alignment, rDNS, and basic TLS hygiene. Use this internal guide: Email Deliverability Setup Guide Tutorial (2026).

Step 1 — Verify inbound STARTTLS and certificate on port 25

From any Linux box (or your laptop with OpenSSL), confirm your MX advertises STARTTLS. Also confirm it presents a valid certificate that matches the MX hostname.

MX=mx1.example.com
openssl s_client -starttls smtp -connect ${MX}:25 -servername ${MX} -showcerts </dev/null

What “good” looks like:

  • You see 250-STARTTLS in the SMTP capabilities.
  • The certificate chain verifies cleanly (Verify return code: 0 (ok)).
  • The certificate CN/SAN includes mx1.example.com.

Quick diagnostic if it fails:

  • No STARTTLS advertised: confirm Postfix has TLS enabled (common setting: smtpd_tls_security_level = may at minimum).
  • Hostname mismatch: you’re presenting a cert for a different name (install a certificate that matches the MX hostname).
  • Chain issues: install the full chain and point Postfix at the correct file(s).

If you need a current, reliable Let’s Encrypt flow for Nginx or Apache, follow: SSL Certificate Setup Guide Tutorial (2026).

Step 2 — Decide your MTA-STS policy mode (testing vs enforcement)

MTA-STS supports three modes:

  • none: disables policy (rarely useful once you’ve started).
  • testing: senders may still deliver if they can’t meet policy, but they’ll generate TLS-RPT reports. Plan for 7–14 days here.
  • enforce: senders must meet your policy or they’ll defer/deny delivery.

For most VPS mail setups in 2026, start with testing. Switch to enforce once reports look clean and stable.

That flip is where you catch expiring certs and accidental MX edits. It also closes off silent downgrade paths.

Step 3 — Create the MTA-STS policy file

The policy is a plaintext file served over HTTPS at:

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

Create the file on your web host. If you’re using Nginx on the same VPS, this layout works well:

sudo mkdir -p /var/www/mta-sts/.well-known
sudo nano /var/www/mta-sts/.well-known/mta-sts.txt

Example policy (adjust MX names and mode):

version: STSv1
mode: testing
mx: mx1.example.com
mx: mx2.example.com
max_age: 604800
  • mx: must match the MX hostnames you publish in DNS (or a pattern you control). Include every valid inbound MX host.
  • max_age: in seconds. Start with 604800 (7 days). Once things are stable, move to 2592000 (30 days).

Pitfall: don’t put IP addresses in the policy. Only hostnames are valid.

Step 4 — Serve the policy over HTTPS on mta-sts.yourdomain

You need an HTTPS vhost with a valid certificate for mta-sts.example.com. It can live on the same VPS as Postfix or on a different web server.

What matters is reliability. The endpoint must stay reachable and must serve the correct file consistently.

Nginx example vhost

Create an Nginx server block (Debian/Ubuntu paths shown):

sudo nano /etc/nginx/sites-available/mta-sts.example.com
server {
  listen 80;
  server_name mta-sts.example.com;

  location /.well-known/mta-sts.txt {
    root /var/www/mta-sts;
    default_type text/plain;
  }
}

Enable it and reload:

sudo ln -s /etc/nginx/sites-available/mta-sts.example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Now issue a certificate (Certbot example):

sudo apt update
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d mta-sts.example.com

Re-check the URL:

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

You should see 200 OK and the policy body.

If renewals start misbehaving later, use this internal guide instead of poking at config under pressure: Let’s Encrypt Renewal Troubleshooting Tutorial (2026).

Step 5 — Publish the DNS TXT records (MTA-STS + TLS-RPT)

You’ll publish two TXT records:

  1. MTA-STS policy discovery at _mta-sts.example.com
  2. TLS reporting at _smtp._tls.example.com

5.1 MTA-STS TXT record

Name/Host: _mta-sts (some DNS UIs require full: _mta-sts.example.com)

Value:

v=STSv1; id=2026100601

id is your change token. Update it whenever you change the policy file (mode, MX list, etc.). A simple YYYYMMDDNN format is easy to track.

5.2 TLS-RPT TXT record

Name/Host: _smtp._tls

Value (send reports to a mailbox you actually read):

v=TLSRPTv1; rua=mailto:tls-rpt@example.com

Use a dedicated address so reports don’t get buried.

If you host mail on the same VPS, create that mailbox first. Then verify it receives mail from outside your domain.

If you want a safer DNS change window, follow the internal cutover process so you can validate and roll back cleanly: DNS Cutover Tutorial (2026).

Step 6 — Validate DNS propagation and policy fetch

From a terminal, confirm both TXT records resolve:

dig +short TXT _mta-sts.example.com
dig +short TXT _smtp._tls.example.com

Then verify the policy file is reachable over HTTPS:

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

If curl fails, stop and fix that first. Enforcement depends on senders being able to fetch the policy reliably.

Step 7 — Tighten your inbound SMTP TLS settings (Postfix side)

Postfix doesn’t “turn on MTA-STS.” Your job is to provide stable STARTTLS with a valid certificate.

Before you publish a strict policy, make sure inbound TLS won’t wobble during renewals or restarts.

On the mail server, review /etc/postfix/main.cf. Typical 2026-safe defaults for inbound SMTP include:

smtpd_tls_security_level = may
smtpd_tls_cert_file = /etc/letsencrypt/live/mx1.example.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mx1.example.com/privkey.pem
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
# Prefer modern protocols; avoid legacy if you can.
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
# Ciphers depend on OpenSSL build; keep it practical.
tls_preempt_cipherlist = yes

Reload Postfix after changes:

sudo postfix check
sudo systemctl reload postfix

Practical pitfall: if you run multiple MX hosts, every one must be correct. One broken secondary MX (bad cert, STARTTLS disabled, port 25 blocked) can trigger delivery failures once you switch to enforce.

Step 8 — Run in “testing” and read your TLS-RPT reports

Leave mode: testing in place for at least a week. While it runs:

  • Watch for reports mentioning certificate expired, hostname mismatch, or no STARTTLS.
  • Make sure the policy hostname stays up through maintenance windows and reboots.
  • If you change MX records, update the policy file and bump the DNS id.

TLS-RPT reports typically arrive as JSON attachments (often gzip). You can keep them in a mailbox and spot-check, or parse them later.

Even without tooling, the top failure reasons are usually obvious.

Step 9 — Switch to “enforce” safely

Once reports stay clean, edit the policy file:

sudo nano /var/www/mta-sts/.well-known/mta-sts.txt

Change:

mode: enforce

Then bump the DNS id value (this is what prompts senders to re-fetch):

v=STSv1; id=2026100602

Keep max_age at 7 days for the first enforcement window. After two stable weeks, raise it to 30 days to reduce policy fetch frequency.

Common breakages (and the fast fix)

  • Your MX certificate renewed, but Postfix still serves the old cert: reload Postfix after renewal, and confirm file paths point to the active live/ symlinks.
  • Policy lists the wrong MX hostnames: update mx: entries to match DNS exactly. Don’t list aliases unless they are actual MX targets.
  • mta-sts subdomain missing/incorrect A/AAAA: add correct records so senders can fetch HTTPS policy.
  • CDN/proxy misconfiguration: keep the policy endpoint simple. Avoid redirects and auth.
  • Firewall blocks port 25 intermittently: verify local firewall plus any provider firewall rules. If you need a clean baseline, follow VPS Firewall Setup Guide Tutorial (2026) and explicitly allow SMTP.

Operational checklist for resellers and multi-domain hosting

If you host mail for multiple customer domains on one VPS, handle MTA-STS per domain. Don’t treat it as a single global switch.

  • Create one mta-sts.customer-domain.tld vhost per domain (or a single server that can serve multiple vhosts).
  • Track policy id bumps alongside DNS changes in your change log.
  • Set calendar alerts for certificate expiry even with automation. Expiry + enforce can cause immediate inbound failures.
  • Only run a secondary MX if you can keep TLS and certificates correct there too.

Summary: strict TLS for inbound mail, without changing your mail clients

MTA-STS is one of the few email upgrades that’s mostly “publish, then monitor.” You post a strict policy, keep MX certificates valid, and let large senders enforce TLS for you.

For a business domain, that’s a clear security improvement. For a hosting VPS, it also reduces support churn because failures show up as reports, not mysteries.

If you’re planning a mail move, enable MTA-STS after the migration settles. Or keep the policy in testing until cutover is complete.

Pair it with controlled DNS changes and a VPS setup you can manage. For reliable mail and tighter DNS control, start with managed VPS hosting from HostMyCode so renewals, firewall baselines, and service uptime don’t turn into late-night surprises.

Running email on a VPS goes smoother when you control DNS, rDNS, TLS, and monitoring from day one. HostMyCode offers HostMyCode VPS plans for hands-on admins, plus managed VPS hosting if you want the platform maintained while you focus on domains and customers.

FAQ

Does Postfix need a special plugin to “enable MTA-STS”?

No. Sending mail servers enforce MTA-STS. Your job is to provide consistent STARTTLS with a valid certificate on your MX, then publish the policy via HTTPS and DNS.

Can I host the MTA-STS policy on a different server than my mail server?

Yes. The policy is just an HTTPS endpoint. Many admins serve it from a web server or a separate small VPS, as long as it’s reliable and uses a valid certificate.

Should I use “testing” or “enforce” first?

Use testing for 7–14 days, read TLS-RPT reports, fix any certificate or STARTTLS issues, then switch to enforce and bump the DNS id.

Will MTA-STS stop spam?

No. It enforces transport encryption. For spam control you still need SPF/DKIM/DMARC, sane rate limits, and content filtering.

What breaks most often after enabling enforce?

Expired or mismatched certificates on a secondary MX, and policy files that list the wrong hostnames. Keep the policy MX list aligned with DNS, and automate certificate renewal plus service reloads.