Postfix's header_checks functionality is a powerful spam filtering tool that examines message headers against regular expression patterns. The configuration you've shown:
header_checks = regexp:/etc/postfix/header_checks
is technically correct, but several factors could prevent it from working as expected.
Your question about the /i
modifier is valid. While many regex engines support this flag, Postfix's implementation has limitations:
# This works in most regex engines but not in Postfix:
/^Subject:.*viagra.*/i DISCARD
# Postfix alternative (character classes):
/^Subject:.*[vV][iI][aA][gG][rR][aA].*/ DISCARD
Several issues could explain why your filters aren't catching test emails:
- Header folding: Email clients often split long headers across multiple lines
- Character encoding: Non-ASCII characters might bypass simple pattern matching
- Header order: The From: header might appear after Subject: in actual messages
For different handling of spam messages, consider these alternatives:
# Reject with 550 error (bounces to sender)
/^Subject:.*viagra.*/ REJECT Spam detected
# Redirect to spam folder (requires maildir support)
/^Subject:.*pills.*/ REDIRECT spam@yourdomain.com
# Tag message header (doesn't block but marks it)
/^From:.*spammer.com/ WARN Possible spam source
To verify your filters without sending real emails:
postmap -q "Subject: cheap VIAGRA" regexp:/etc/postfix/header_checks
Remember to reload Postfix after configuration changes:
postfix reload
For more robust spam filtering, combine header_checks with other techniques:
# Match multiple variations
/^Subject:.*(viagra|cialis|levitra).*/ DISCARD
# Handle base64 encoded subjects
/^Subject:.*=\?.*viagra.*\?=/ DISCARD
# Check multiple headers in one rule
/^(From|Subject|Reply-To):.*pharmacy.*/ DISCARD
When implementing spam filtering in Postfix using header_checks
, I encountered unexpected behavior where emails containing spam keywords in subjects weren't being filtered properly. Here's my original configuration:
# main.cf
header_checks = regexp:/etc/postfix/header_checks
The current regex patterns in /etc/postfix/header_checks
appear correct at first glance:
/^Subject:.*viagra.*/i DISCARD
/^Subject:.*pills.*/i DISCARD
/^Subject:.*f\\*ckbuddy.*/i DISCARD
/^Subject:.*f\\*ckfriend.*/i DISCARD
/^Subject:.*f\\@ck.*/i DISCARD
/^From:.*viagra.*/i DISCARD
I conducted tests by sending emails from Hotmail containing these keywords in various cases (e.g., "ViAgRa", "PILLS") but the messages weren't being filtered. Here's what I discovered:
After making changes to header_checks, you must properly reload Postfix:
sudo postfix reload
Or alternatively:
sudo systemctl reload postfix
Instead of DISCARD, you can use REJECT to return a message to sender:
/^Subject:.*viagra.*/i REJECT Spam detected
To verify Postfix is actually processing your header_checks:
sudo postconf -n | grep header_checks
sudo postconf -e "header_checks = pcre:/etc/postfix/header_checks"
sudo postmap -q "Subject: viagra special offer" pcre:/etc/postfix/header_checks
For more powerful pattern matching, consider using PCRE instead of regexp:
header_checks = pcre:/etc/postfix/header_checks
With corresponding syntax changes in your patterns file.
The /i
modifier is indeed supported in Postfix regex patterns. The issue likely stems from either:
- Not properly reloading Postfix after changes
- Mail client header variations
- MIME encoding in subjects
Here's a verified working configuration:
# /etc/postfix/main.cf
header_checks = pcre:/etc/postfix/header_checks
# /etc/postfix/header_checks
/^Subject:\s*.*viagra.*/i REJECT Spam detected
/^Subject:\s*.*(pills|pharmacy|cialis).*/i DISCARD
/^From:.*@spamdomain\.com$/ REJECT Known spam source