Email Deliverability Optimization Guide
Email deliverability determines whether your messages reach inboxes or get silently dropped by spam filters. This guide covers IP reputation management, SPF/DKIM/DMARC configuration, IP warm-up strategies, blacklist monitoring, and bounce handling for Linux mail servers.
Prerequisites
- A Linux mail server (Postfix + Dovecot or equivalent)
- A dedicated IP address (not shared with other senders)
- Control over your domain's DNS records
- Reverse DNS (PTR record) set correctly
- Root or sudo access
DNS Authentication Setup
SPF (Sender Policy Framework) declares which servers may send mail for your domain:
# Basic SPF record - add as TXT record at yourdomain.com
# v=spf1 mx -all
# Explanation: allow the MX host to send, reject all others
# If you send from multiple servers:
# v=spf1 mx ip4:203.0.113.10 ip4:203.0.113.11 -all
# If you use a third-party sending service too:
# v=spf1 mx include:sendgrid.net -all
# Verify SPF record is correct
dig TXT yourdomain.com | grep spf
SPF alignment rules:
- Use
-all(hard fail) for best reputation - Use
~all(soft fail) initially while warming up - Never use
+all(allow everything)
# Test SPF from command line
apt install -y libmail-spf-perl
spfquery [email protected] --ip=YOUR_SERVER_IP --helo=mail.yourdomain.com
DKIM Configuration
DKIM signs outgoing messages with a private key that receivers verify via DNS:
# Install opendkim if not already done
apt install -y opendkim opendkim-tools
# Generate keys
mkdir -p /etc/opendkim/keys/yourdomain.com
opendkim-genkey -b 2048 -d yourdomain.com -D /etc/opendkim/keys/yourdomain.com -s mail -v
# View the DNS TXT record to add
cat /etc/opendkim/keys/yourdomain.com/mail.txt
# Add this as a TXT record: mail._domainkey.yourdomain.com
# Set permissions
chown -R opendkim:opendkim /etc/opendkim/keys/
chmod 600 /etc/opendkim/keys/yourdomain.com/mail.private
Configure OpenDKIM:
cat > /etc/opendkim.conf << 'EOF'
Domain yourdomain.com
KeyFile /etc/opendkim/keys/yourdomain.com/mail.private
Selector mail
Socket inet:12301@localhost
Mode sv
SubDomains No
AutoRestart Yes
AutoRestartRate 10/1m
Background Yes
DNSTimeout 5
SignatureAlgorithm rsa-sha256
OversignHeaders From
EOF
# Integrate with Postfix
postconf -e 'milter_protocol = 6'
postconf -e 'milter_default_action = accept'
postconf -e 'smtpd_milters = inet:127.0.0.1:12301'
postconf -e 'non_smtpd_milters = inet:127.0.0.1:12301'
systemctl enable --now opendkim
systemctl reload postfix
Verify DKIM signing:
# Send a test message and check headers for "DKIM-Signature"
echo "Test" | mail -s "DKIM Test" [email protected]
# Use a tool to verify
opendkim-testkey -d yourdomain.com -s mail -vvv
DMARC Policy Setup
DMARC builds on SPF and DKIM to instruct receivers what to do with failing messages:
# Start with a monitoring-only policy to collect reports
# Add as TXT record: _dmarc.yourdomain.com
# v=DMARC1; p=none; rua=mailto:[email protected]; ruf=mailto:[email protected]; fo=1
# After 2-4 weeks of reports, move to quarantine
# v=DMARC1; p=quarantine; pct=25; rua=mailto:[email protected]
# Finally, move to reject (full enforcement)
# v=DMARC1; p=reject; rua=mailto:[email protected]; adkim=s; aspf=s
Parse DMARC aggregate reports with a tool:
# Install dmarc-cat or similar
pip3 install dmarc-cat
# Parse a DMARC report XML file
dmarc-cat report.xml.gz
IP Reputation Management
Your sending IP's reputation is critical for deliverability:
# Check your IP's current reputation
# Visit: https://mxtoolbox.com/blacklists.aspx
# Or use:
host -l YOUR_SERVER_IP zen.spamhaus.org
host -l YOUR_SERVER_IP bl.spamcop.net
# Automate reputation checks
cat > /usr/local/bin/check-ip-reputation.sh << 'EOF'
#!/bin/bash
IP=${1:-$(curl -s ifconfig.me)}
LISTS=(
"zen.spamhaus.org"
"bl.spamcop.net"
"dnsbl.sorbs.net"
"b.barracudacentral.org"
"dnsbl-1.uceprotect.net"
)
REVERSED=$(echo $IP | awk -F. '{print $4"."$3"."$2"."$1}')
echo "Checking IP: $IP"
for LIST in "${LISTS[@]}"; do
RESULT=$(host -t A "${REVERSED}.${LIST}" 2>/dev/null | grep -v "not found" | grep "has address")
if [ -n "$RESULT" ]; then
echo "LISTED on $LIST: $RESULT"
else
echo "Clean on $LIST"
fi
done
EOF
chmod +x /usr/local/bin/check-ip-reputation.sh
Configure Postfix to improve reputation:
# Set a legitimate HELO hostname
postconf -e 'myhostname = mail.yourdomain.com'
postconf -e 'smtp_helo_name = mail.yourdomain.com'
# Don't relay open spam
postconf -e 'smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination'
# Rate limit outgoing mail to avoid spam flag triggers
postconf -e 'smtp_destination_rate_delay = 1s'
postconf -e 'default_destination_concurrency_limit = 5'
IP Warm-Up Strategy
New IPs have no reputation. Mailbox providers (Gmail, Microsoft) need to see consistent, low-volume sending first:
| Day Range | Daily Volume |
|---|---|
| Days 1-3 | 50-100 |
| Days 4-7 | 200-500 |
| Week 2 | 1,000-2,000 |
| Week 3 | 5,000-10,000 |
| Week 4+ | Scale up 2x weekly |
Key warm-up rules:
- Send only to engaged recipients first (recent openers/clickers)
- Maintain low bounce rate (< 2%)
- Maintain low spam complaint rate (< 0.1%)
- Send consistently - gaps reset reputation
Script to throttle outgoing mail volume:
# Postfix rate limiting per hour
# In /etc/postfix/main.cf:
# default_destination_rate_delay = 60s # 1 message per minute per destination
# smtp_destination_concurrency_limit = 2 # Max 2 connections per recipient server
Blacklist Monitoring and Removal
Set up automated blacklist monitoring:
# Install mxtoolbox CLI or use a service like HetrixTools
# Simple cron-based monitoring:
cat > /etc/cron.daily/check-blacklists << 'EOF'
#!/bin/bash
RESULT=$(/usr/local/bin/check-ip-reputation.sh 2>&1)
if echo "$RESULT" | grep -q "LISTED"; then
echo "$RESULT" | mail -s "IP BLACKLISTED - Action Required" [email protected]
fi
EOF
chmod +x /etc/cron.daily/check-blacklists
Removal process by list:
- Spamhaus: Complete automatic lookup form at
lookup.spamhaus.org - SpamCop: Wait for automatic expiry (24-48 hours after stopping spam)
- Barracuda: Submit removal at
barracudacentral.org/rbl/removal - Sorbs: Email
[email protected]with justification
Bounce Handling
Bounces indicate invalid addresses and damage your reputation:
# Monitor Postfix bounce logs
tail -f /var/log/mail.log | grep -E 'status=bounced|status=deferred'
# Parse bounce reasons
postcat -q $(mailq | grep -oP '^[A-F0-9]{10,}' | head -1) | grep -A5 "bounce"
# Common bounce types and actions:
# 5xx (hard bounce) - Remove address permanently
# 4xx (soft bounce) - Retry, remove after 3-5 failures
Process bounce notifications automatically:
# Configure a bounce handling address in Postfix
postconf -e 'bounce_notice_recipient = [email protected]'
postconf -e 'error_notice_recipient = [email protected]'
# Use a service like Postal or Haraka with bounce processing
# Or write a script to parse MDN/DSN messages
Testing and Monitoring
# Full deliverability test (use mail-tester.com)
# Send a test message to the address shown on mail-tester.com
# Score of 9-10/10 is the target
# Check MX, SPF, DKIM, DMARC via MXToolbox
curl "https://mxtoolbox.com/api/v1/Lookup/MX/?argument=yourdomain.com" 2>/dev/null
# Test from Gmail - check the message's "Show original" headers
# Look for: "DKIM: PASS", "SPF: PASS", "DMARC: PASS"
# Monitor postfix queue
watch -n 30 'postqueue -p | tail -5'
# Check hourly send volumes
grep "status=sent" /var/log/mail.log | grep "$(date +%b\ %e\ %H)" | wc -l
Troubleshooting
Gmail showing "via yourdomain.com" in from header (SPF alignment issue):
Ensure the MAIL FROM envelope sender domain matches your From header domain, or use DKIM with adkim=r (relaxed).
Messages delivered but immediately marked as spam:
# Check content triggers
spamassassin -t < test_message.eml | head -50
# Check if sending IP is shared and already has a bad reputation
# Request a dedicated IP from your VPS provider
DMARC reports showing SPF/DKIM failures for some messages:
Some email services (forwarding, mailing lists) break SPF/DKIM alignment. Enable ARC signing on your server and work with forwarding services.
Conclusion
Email deliverability is a combination of technical authentication (SPF/DKIM/DMARC), IP reputation management, and responsible sending practices. Configure all three authentication mechanisms before sending any bulk mail, monitor blacklists continuously, and handle bounces aggressively to maintain a clean list. A well-maintained sending infrastructure consistently achieves inbox placement rates above 95%.


