Optimal Postfix smtpd_recipient_restrictions Configuration to Block 1000+ Spam Emails/Minute


5 views

After inheriting DNS from another ISP, our mail server got crushed under 1000+ spam emails per minute. The existing Postfix configuration couldn't handle this volume, requiring immediate optimization of smtpd_recipient_restrictions.

Environment setup:

Ubuntu Server
Postfix MTA
Amavis for content filtering
MySQL for virtual domains
Fail2Ban for blocking abusive IPs

This Postfix configuration reduced spam by 90%:

smtpd_recipient_restrictions = 
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_non_fqdn_hostname,
    reject_invalid_hostname,
    reject_non_fqdn_sender,
    reject_unknown_sender_domain,
    reject_non_fqdn_recipient,
    reject_unknown_recipient_domain,
    check_policy_service inet:127.0.0.1:10023,  # Portgrey/Policyd-weight
    reject_rbl_client zen.spamhaus.org,
    check_recipient_access mysql:/etc/postfix/mysql-virtual_recipient.cf,
    reject_unauth_pipelining,
    reject_unauth_destination

DNSBL Checks: reject_rbl_client zen.spamhaus.org blocks known spam sources. Combine with other RBLs like bl.spamcop.net for better coverage.

Policy Daemon: The check_policy_service line integrates Policyd-weight or Portgrey for reputation scoring and rate limiting.

MySQL Integration: check_recipient_access verifies valid recipients against your database:

# /etc/postfix/mysql-virtual_recipient.cf
user = mailadmin
password = YourSecurePassword
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_users WHERE email='%s'

Combine with these postfix parameters:

smtpd_delay_reject = yes
smtpd_helo_required = yes
smtpd_helo_restrictions = 
    permit_mynetworks,
    reject_invalid_helo_hostname,
    reject_non_fqdn_helo_hostname

Order matters in smtpd_recipient_restrictions. Place faster checks first:

  1. Local networks/SASL authenticated users
  2. Basic syntax checks
  3. DNS/RBL lookups
  4. Database/MTA policy checks

When inheriting DNS infrastructure from another ISP, mail servers often become immediate targets for spammers. The original configuration showed nearly 1,000 spam messages per minute hitting the server, which is completely unsustainable for any production environment.

The working solution combines multiple defense layers:

smtpd_recipient_restrictions = 
permit_mynetworks,
permit_sasl_authenticated,
reject_non_fqdn_hostname,
reject_invalid_hostname,
reject_non_fqdn_sender,
reject_unknown_sender_domain,
reject_non_fqdn_recipient,
reject_unknown_recipient_domain,
check_policy_service inet:127.0.0.1:10023,
reject_rbl_client zen.spamhaus.org,
check_recipient_access mysql:/etc/postfix/mysql-virtual_recipient.cf,
reject_unauth_pipelining,
reject_unauth_destination

1. Early Rejection of Invalid Traffic
The configuration prioritizes rejecting obviously invalid messages before they consume significant resources:

  • reject_non_fqdn_hostname
  • reject_invalid_hostname
  • reject_non_fqdn_sender

2. DNS-Based Blacklisting
The zen.spamhaus.org RBL check provides immediate blocking of known spam sources:

reject_rbl_client zen.spamhaus.org

For high-volume environments, integrating external services proves critical:

check_policy_service inet:127.0.0.1:10023  # Portgrey/Postgrey integration
check_recipient_access mysql:/etc/postfix/mysql-virtual_recipient.cf

The ordering of restrictions matters significantly - we place resource-intensive checks (like RBL lookups) after simpler rejections. This prevents unnecessary DNS queries for obviously invalid messages.

After implementing these changes, spam levels decreased by 90% as shown in the monitoring graph:

Spam traffic reduction graph

  • Consider adding more RBL providers (like spamcop.net)
  • Implement rate limiting with anvil(8)
  • Add DKIM/DMARC verification for additional filtering