Implementing Separate Header Checks for Inbound vs Outbound Mail in Postfix


6 views

Postfix applies header checks uniformly to all email traffic by default, which presents challenges when you need different filtering rules for incoming versus outgoing messages. The header_checks parameter in main.cf doesn't distinguish between message directions.

The key is leveraging Postfix's service-specific configuration capabilities. We'll create separate header check files and apply them to different Postfix services:

# In main.cf
# For incoming mail (smtpd service)
smtpd_header_checks = pcre:/etc/postfix/inbound_header_checks.pcre

# For outgoing mail (cleanup service)
header_checks = pcre:/etc/postfix/outbound_header_checks.pcre

Sample inbound header checks (blocking specific patterns from external senders):

/^X-Spam-Flag:.*YES/ REJECT Spam detected
/^Subject:.*(viagra|loan)/ REJECT Blocked content

Sample outbound header checks (ensuring proper headers from your domain):

/^Message-ID:.*!/ WARN Missing valid Message-ID
/^DKIM-Signature:/ IGNORE

When implementing this solution:

  • Remember to run postmap on PCRE files if needed
  • Test with postmap -q before deploying
  • Monitor mail logs for false positives

For more granular control, you can combine this with client-specific restrictions:

smtpd_client_restrictions = 
    check_client_access hash:/etc/postfix/client_header_checks

Where client_header_checks maps IPs to specific header check files.

Header checks add processing overhead. For high-volume servers:

  • Use simpler regex patterns for inbound mail
  • Consider compiling PCRE patterns with -O2 optimization
  • Monitor qmgr queue times after implementation

Postfix applies header_checks uniformly to all email messages by default, whether they're incoming or outgoing. This can create operational challenges when you need different filtering rules for external messages versus those originating from your own users.

Common scenarios requiring separate handling:

  • Strict inbound spam filtering while allowing legitimate outbound headers
  • Removing sensitive headers from outgoing mail but preserving them internally
  • Different regex patterns for internal versus external message validation

The key is to leverage Postfix's modular architecture. We'll configure separate header_checks for the smtpd service (incoming) and cleanup service (outgoing).

# In main.cf
# For incoming mail (via smtpd)
smtpd_header_checks = regexp:/etc/postfix/inbound_header_checks

# For outgoing mail (via cleanup)
header_checks = regexp:/etc/postfix/outbound_header_checks

inbound_header_checks:

/^X-Spam-Flag: YES/ REJECT Spam detected
/^Subject:.*(viagra|porn)/ REJECT Inappropriate content

outbound_header_checks:

/^X-Internal:.*/ REDACT [REDACTED]
/^Subject:.*(confidential|secret)/ WARN Sensitive subject detected
  • Remember to run postmap on regex files if using hash or pcre formats
  • Test configurations with postfix check before reloading
  • Monitor mail logs during initial deployment

For complex setups, you can apply different rules based on receiving interface:

# In master.cf
submission inet n - - - - smtpd
  -o smtpd_header_checks=regexp:/etc/postfix/submission_header_checks