MTA-STS Implementation Guide for Postfix + RSPAMD 3.4
Complete MTA-STS Implementation Guide for Postfix + RSPAMD 3.4
Overview
This guide provides a real-world tested approach to implementing MTA-STS (Mail Transfer Agent Strict Transport Security) with Postfix and RSPAMD 3.4, including complete troubleshooting based on actual deployment experience.
Important: This guide is based on successful deployment with RSPAMD 3.4, which has limited native MTA-STS support. MTA-STS works primarily through Postfix, DNS, and web infrastructure.
Prerequisites
- Working Postfix mail server with TLS configured
- RSPAMD 3.4 installed and running
- Apache web server with SSL/TLS certificates
- DNS control for your domains
- Example domains used:
testedbymatt.com
andmatthewdavidson.us
Phase 1: Infrastructure Setup
Step 1: Verify Postfix TLS Configuration
Ensure your existing Postfix TLS setup is working:
1
2
# Check main.cf has these essential settings
grep -E "(smtpd_tls_cert|smtpd_tls_key|smtpd_tls_security)" /etc/postfix/main.cf
Your main.cf
should include:
1
2
3
4
5
6
7
8
9
# TLS for incoming connections
smtpd_tls_cert_file=/etc/letsencrypt/live/mail.yourdomain.com/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/mail.yourdomain.com/privkey.pem
smtpd_tls_security_level=may
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
# TLS for outgoing connections
smtp_tls_security_level = may
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
Critical: Do NOT add smtp_tls_policy_maps
lines - these cause errors in RSPAMD 3.4 setups.
Step 2: Test Mail Server TLS
1
echo "QUIT" | openssl s_client -connect mail.yourdomain.com:25 -starttls smtp 2>/dev/null | grep "Verify return code"
Expected: Verify return code: 0 (ok)
Step 3: Check MX Records
Critical Step: Your MTA-STS policy MUST exactly match your MX records.
1
2
dig MX yourdomain.com +short
dig MX anotherdomain.com +short
Document these results - you’ll need them for the policy files.
Phase 2: MTA-STS Policy Files
Step 1: Create Directory Structure
1
2
mkdir -p /var/www/mta-sts.yourdomain.com/.well-known/
mkdir -p /var/www/mta-sts.anotherdomain.com/.well-known/
Step 2: Create Policy Files
Critical: The mx:
entries must EXACTLY match your MX records from Step 3 above.
/var/www/mta-sts.yourdomain.com/.well-known/mta-sts.txt
:
1
2
3
4
version: STSv1
mode: enforce
mx: mail.yourdomain.com
max_age: 86400
If you have multiple MX records, list them ALL: /var/www/mta-sts.anotherdomain.com/.well-known/mta-sts.txt
:
1
2
3
4
5
version: STSv1
mode: enforce
mx: mail.anotherdomain.com
mx: mail.yourdomain.com
max_age: 86400
Step 3: Configure Apache Virtual Hosts
Create /etc/apache2/sites-available/mta-sts.yourdomain.com.conf
:
1
2
3
4
5
6
<VirtualHost *:80>
ServerName mta-sts.yourdomain.com
DocumentRoot /var/www/mta-sts.yourdomain.com
RewriteEngine on
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
Create /etc/apache2/sites-available/mta-sts.yourdomain.com-le-ssl.conf
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName mta-sts.yourdomain.com
DocumentRoot /var/www/mta-sts.yourdomain.com
<Directory /var/www/mta-sts.yourdomain.com>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# Ensure .well-known directory is accessible
<Directory "/var/www/mta-sts.yourdomain.com/.well-known">
Require all granted
</Directory>
SSLCertificateFile /etc/letsencrypt/live/mta-sts.yourdomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mta-sts.yourdomain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
ErrorLog ${APACHE_LOG_DIR}/mta-sts.yourdomain.com_error.log
CustomLog ${APACHE_LOG_DIR}/mta-sts.yourdomain.com_access.log combined
</VirtualHost>
</IfModule>
Repeat for each domain, then:
1
2
3
a2ensite mta-sts.yourdomain.com
a2ensite mta-sts.yourdomain.com-le-ssl
systemctl reload apache2
Step 4: Test Policy File Access
1
2
curl -s https://mta-sts.yourdomain.com/.well-known/mta-sts.txt
curl -s https://mta-sts.anotherdomain.com/.well-known/mta-sts.txt
Both should return your policy content with HTTP 200.
Phase 3: DNS Configuration
Step 1: Add MTA-STS DNS Records
CRITICAL: DNS record formatting is crucial. Use EXACTLY this format:
_mta-sts.yourdomain.com. IN TXT "v=STSv1; id=20250809"
_mta-sts.anotherdomain.com. IN TXT "v=STSv1; id=20250809"
Common Error: Do NOT use escaped quotes like "\"v=STSv1; id=20250809\""
- this breaks external discovery.
Step 2: Verify DNS Records
1
2
dig TXT _mta-sts.yourdomain.com +short
dig TXT _mta-sts.anotherdomain.com +short
Both should return: "v=STSv1; id=20250809"
NOT: "\"v=STSv1; id=20250809\""
Step 3: Test DNS from Multiple Servers
1
2
3
4
# Test from different DNS servers to ensure propagation
dig @8.8.8.8 TXT _mta-sts.yourdomain.com +short
dig @1.1.1.1 TXT _mta-sts.yourdomain.com +short
dig @208.67.222.222 TXT _mta-sts.yourdomain.com +short
Phase 4: External Validation (CRITICAL)
This step is essential - internal testing doesn’t catch DNS formatting issues.
Step 1: Use External MTA-STS Validators
Test each domain with these external tools:
- Mailhardener: https://www.mailhardener.com/tools/mta-sts-validator
- EasyDMARC: https://easydmarc.com/tools/mta-sts-check
- MxToolbox: https://mxtoolbox.com/mta-sts.aspx
Step 2: Expected Validation Results
Success indicators:
- “Record is valid”
- “MTA-STS policy is published and served”
- “Certificate is valid”
- Mode shows “enforce”
- MX records listed correctly
Failure indicators requiring fixes:
- “MTA-STS DNS record not found” (usually DNS formatting issue)
- “Policy file not accessible” (HTTPS/certificate issue)
- “MX mismatch” (policy doesn’t match actual MX records)
Phase 5: RSPAMD Configuration (Optional)
RSPAMD 3.4 doesn’t have native MTA-STS modules, but you can add domain tracking.
Step 1: Create Multimap Configuration
/etc/rspamd/local.d/multimap.conf
:
1
2
3
4
5
6
7
8
# MTA-STS domain tracking (optional)
MTA_STS_DOMAINS {
type = "from";
map = "/etc/rspamd/mta_sts_domains.map";
description = "Domains with MTA-STS policies";
score = 0.0;
action = "no action";
}
Step 2: Create Domain Map
/etc/rspamd/mta_sts_domains.map
:
1
2
yourdomain.com MTA_STS
anotherdomain.com MTA_STS
Step 3: Test and Restart
1
2
rspamadm configtest
systemctl restart rspamd
Look for MTA_STS(1.00){yourdomain.com;}
in RSPAMD logs.
Phase 6: TLS Reporting Setup
Step 1: Create Report Email Addresses
Ensure these email addresses work:
tls-reports@yourdomain.com
tls-reports@anotherdomain.com
Step 2: Add TLS-RPT DNS Records
_smtp._tls.yourdomain.com. IN TXT "v=TLSRPTv1; rua=mailto:tls-reports@yourdomain.com"
_smtp._tls.anotherdomain.com. IN TXT "v=TLSRPTv1; rua=mailto:tls-reports@anotherdomain.com"
Step 3: Verify TLS-RPT Records
1
2
dig TXT _smtp._tls.yourdomain.com +short
dig TXT _smtp._tls.anotherdomain.com +short
Should return: "v=TLSRPTv1; rua=mailto:tls-reports@yourdomain.com"
Phase 7: Testing and Monitoring
Step 1: Send Test Emails
Send emails from external providers (Gmail, Outlook, Yahoo) to your domains.
Step 2: Monitor Logs
Postfix logs (successful TLS):
1
journalctl -u postfix | grep -i tls
Look for: TLS connection established to...
RSPAMD logs (MTA-STS detection):
1
tail -f /var/log/rspamd/rspamd.log | grep MTA_STS
Look for: MTA_STS(1.00){yourdomain.com;}
Apache logs (policy fetches):
1
tail -f /var/log/apache2/mta-sts.yourdomain.com_access.log
Look for external IPs (not your server IP) fetching mta-sts.txt
Step 3: What to Expect
Immediate (after DNS propagation):
- External validators pass
- Internal email delivery works
- TLS connections show in logs
Within 24-48 hours:
- External servers fetch your policy files
- TLS reports start arriving (JSON attachments)
- Policy enforcement visible in reports
Major Troubleshooting Scenarios
Issue 1: External Validator Says “DNS Record Not Found”
Symptoms:
- Your
dig
commands work fine - External validators fail
- No external policy fetches in Apache logs
Cause: DNS record has escaped quotes
Diagnosis:
1
dig TXT _mta-sts.yourdomain.com +short
Problem if you see: "\"v=STSv1; id=20250809\""
Should be: "v=STSv1; id=20250809"
Solution: Fix DNS record formatting in your DNS provider interface.
Issue 2: Postfix SMTP Errors
Symptoms:
1
2
error: open database /etc/postfix/tls_policy.db: No such file or directory
fatal: need service transport:endpoint instead of "unix"
Cause: Incorrect smtp_tls_policy_maps
configuration
Solution:
1
2
3
# Remove the problematic line
sed -i 's/smtp_tls_policy_maps.*$/# smtp_tls_policy_maps removed/' /etc/postfix/main.cf
postfix reload
Issue 3: MX Record Mismatch
Symptoms:
- External validators show MX mismatch errors
- Email delivery failures
- Policy shows different MX than DNS
Diagnosis:
1
2
3
4
5
# Check actual MX records
dig MX yourdomain.com +short
# Compare with policy file
cat /var/www/mta-sts.yourdomain.com/.well-known/mta-sts.txt
Solution: Update policy file to include ALL MX records exactly as they appear in DNS.
Issue 4: No External Policy Fetches
Symptoms:
- Only your server IP appears in Apache logs
- No external servers fetching mta-sts.txt
Common Causes:
- DNS formatting issue (see Issue 1)
- Providers cached negative results before your setup
- No external email traffic to trigger fetches
Solutions:
- Fix DNS formatting
- Change DNS
id
parameter to force refresh - Send test emails from multiple external providers
Issue 5: RSPAMD Configuration Errors
Symptoms:
1
configtest: syntax error
Cause: Using non-existent RSPAMD modules
Solution:
1
2
3
4
5
6
# Remove these files if they exist
rm /etc/rspamd/local.d/mta_sts.conf 2>/dev/null
rm /etc/rspamd/local.d/tls_rpt.conf 2>/dev/null
# Only use multimap.conf
rspamadm configtest
Issue 6: Certificate Problems
Symptoms:
- Policy file accessible via HTTP but not HTTPS
- Certificate warnings in external validators
Diagnosis:
1
curl -v https://mta-sts.yourdomain.com/.well-known/mta-sts.txt 2>&1 | grep -E "(certificate|verify)"
Solution: Ensure valid SSL certificates for mta-sts.*
subdomains.
Advanced Configuration
Testing Mode vs Enforce Mode
For initial testing:
1
2
3
4
version: STSv1
mode: testing
mx: mail.yourdomain.com
max_age: 86400
For production:
1
2
3
4
version: STSv1
mode: enforce
mx: mail.yourdomain.com
max_age: 86400
Testing mode logs violations but allows delivery. Enforce mode rejects non-compliant delivery attempts.
Force Policy Refresh
To force external servers to re-fetch your policy:
- Update policy file content
- Change DNS
id
parameter:_mta-sts.yourdomain.com. IN TXT "v=STSv1; id=20250809-2"
- Wait for DNS propagation
- External servers will fetch fresh policy
Multiple Domain Considerations
If multiple domains use the same mail server:
- Each domain needs its own MTA-STS subdomain and certificate
- Each domain needs its own policy file
- Policy files can reference the same MX servers
- DNS records must be added for each domain
Success Verification Checklist
DNS and Web Infrastructure
- DNS records return correct format (no escaped quotes)
- Policy files accessible via HTTPS with valid certificates
- External validators pass for all domains
- MX records exactly match policy statements
Mail Server Function
- Postfix TLS working (verify return code: 0)
- No smtp_tls_policy_maps errors in logs
- RSPAMD configtest passes
- Test emails deliver successfully
External Validation
- All domains pass external MTA-STS validators
- TLS-RPT records properly formatted
- No DNS formatting warnings
Monitoring
- Apache logs show external policy fetches
- RSPAMD logs show MTA-STS domain detection
- TLS reports arriving with successful session counts
Long-term Maintenance
Regular Tasks
- Monitor TLS reports for delivery issues
- Check certificate expiration for mta-sts subdomains
- Update DNS id when changing policies
- Review Apache logs for unusual access patterns
Policy Updates
- Update policy file content
- Change DNS
id
parameter - Test with external validators
- Monitor for external fetches of new policy
Certificate Renewal
Ensure your certificate renewal process includes MTA-STS subdomains:
1
2
# Include in Let's Encrypt renewal
certbot certonly --apache -d mta-sts.yourdomain.com
Conclusion
This guide provides real-world tested MTA-STS implementation with RSPAMD 3.4. The key lessons learned:
- External validation is critical - internal tests miss DNS formatting issues
- DNS record formatting must be exact - escaped quotes break external discovery
- MX record matching is essential - policy must exactly match DNS MX records
- RSPAMD 3.4 limitations - use multimap for tracking, avoid non-existent modules
- TLS reporting provides visibility - essential for monitoring enforcement
Your email infrastructure now enforces TLS encryption for all inbound mail, meeting modern security standards and protecting against man-in-the-middle attacks.