How to Block Inbound Email Attachments (PDF/ZIP) in Postfix Without Affecting Outbound Mail


2 views

When implementing attachment filtering in Postfix, many admins face the challenge of distinguishing between inbound and outbound mail flows. The default behavior applies mime_header_checks universally, which isn't ideal when you only want to filter incoming attachments.

Your current setup in main.cf:

mime_header_checks = regexp:/etc/postfix/blocked_attachments

And the regex pattern in /etc/postfix/blocked_attachments:

/name=[^>]*\.(pdf|zip)/ REJECT

This configuration affects all mail processing, both inbound and outbound. Let's modify this to target only incoming messages.

Postfix provides a specific parameter for incoming SMTP connections:

smtpd_mime_header_checks = regexp:/etc/postfix/blocked_attachments

Remove or comment out the general mime_header_checks line. This change ensures the filter only applies to messages received via SMTP (inbound mail).

Here's how your main.cf should look after modification:

# For inbound mail filtering only
smtpd_mime_header_checks = regexp:/etc/postfix/blocked_attachments

# Remove or comment out the global setting
# mime_header_checks = regexp:/etc/postfix/blocked_attachments

For more granular control, you can implement port-based filtering in master.cf:

# In /etc/postfix/master.cf
smtp      inet  n       -       n       -       -       smtpd
  -o smtpd_mime_header_checks=regexp:/etc/postfix/blocked_attachments

submission inet n       -       n       -       -       smtpd
  -o smtpd_mime_header_checks=

This configuration applies the filter only to port 25 (inbound) while keeping submission port 587 unfiltered.

After making changes, always test and reload Postfix:

postfix check
postfix reload

Verify with test emails containing PDF attachments sent both inbound and outbound to confirm the filter works as intended.

Another method is to combine header checks with MIME filtering:

smtpd_mime_header_checks = regexp:/etc/postfix/blocked_attachments
smtpd_sender_restrictions = check_sender_access regexp:/etc/postfix/local_senders

Where local_senders contains:

/^.*@yourdomain\.com$/ OK

This whitelists local senders while maintaining inbound filtering.


The current configuration in your Postfix setup affects both incoming and outgoing emails because the mime_header_checks parameter applies globally. When you have:

mime_header_checks = regexp:/etc/postfix/blocked_attachments

This filter gets applied to all messages processed by Postfix, regardless of their direction (inbound or outbound).

The proper way to implement attachment blocking for incoming mail only is to use smtpd_mime_header_checks instead, which only applies to messages coming in through SMTP (port 25):

smtpd_mime_header_checks = regexp:/etc/postfix/blocked_attachments

Remove or comment out the mime_header_checks line to prevent it from affecting outgoing messages.

Your current regex pattern in /etc/postfix/blocked_attachments is generally good:

/name=[^>]*\.(pdf|zip)/ REJECT

But we can make it more robust to catch various MIME header formats:

/^Content-(Disposition|Type).*name\s*=\s*"?[^">]*\.(pdf|zip)/i REJECT

Here's what your main.cf should look like for this specific case:

# Inbound attachment filtering
smtpd_mime_header_checks = regexp:/etc/postfix/blocked_attachments

# Outbound settings (no attachment filtering)
mime_header_checks = 

After making changes, always test your configuration:

postfix check
postfix reload

You can verify the behavior by:

  1. Sending a test email with PDF attachment from outside to your server
  2. Sending a test email with PDF attachment from your server to outside

Another approach is to use header_checks with more specific patterns:

smtpd_header_checks = regexp:/etc/postfix/inbound_attachment_checks

With content like:

/^Content-Type:.*application\/pdf/ REJECT PDF attachments not allowed
/^Content-Type:.*application\/zip/ REJECT ZIP archives not allowed

Remember that content filtering adds processing overhead. For high-volume servers, consider:

  • Using PCRE patterns instead of regexp if supported
  • Implementing the filtering at the MTA level with milters
  • Using dedicated content filtering software like Amavisd

If the filtering isn't working as expected:

postconf -n | grep mime
postconf -n | grep smtpd
grep 'reject:' /var/log/maillog

Check Postfix's debug logs for detailed message processing information.