Configuring Postfix SMTP Relay for Whitelist-Only Email Delivery: Restricting Outbound Messages to Approved Recipients


2 views

When implementing recipient whitelisting in Postfix, it's crucial to understand how different components interact. The smtpd_recipient_restrictions parameter only applies to incoming SMTP connections, not messages injected via sendmail or other local submission methods.

To enforce whitelisting for all outbound messages, including those sent via sendmail, you need to modify main.cf:

# Global restrictions for all messages
smtpd_recipient_restrictions =
    reject_unauth_destination
    check_recipient_access hash:/etc/postfix/whitelist

# Additional parameter for local submissions
smtpd_relay_restrictions =
    permit_mynetworks
    reject_unauth_destination
    check_recipient_access hash:/etc/postfix/whitelist

# Critical for sendmail submissions
default_recipient_limit = 1

Your whitelist file should follow this format (e.g., /etc/postfix/whitelist):

# Whitelisted domains (entire domain)
example.com       OK
trusted.org       OK

# Whitelisted individual addresses
admin@example.com OK
support@trusted.org OK

After editing, always remember to:

postmap /etc/postfix/whitelist
systemctl reload postfix

Verify your setup with these commands:

# Test via SMTP
telnet localhost 25
MAIL FROM: you@yourdomain.com
RCPT TO: blocked@external.com

# Test via sendmail
echo "Test" | sendmail -v blocked@external.com

Both methods should now reject non-whitelisted recipients with "554 5.7.1 Recipient address rejected: Access denied"

For more granular control, implement user-specific whitelists:

# In main.cf
smtpd_restriction_classes = user_whitelist
user_whitelist = check_sender_access hash:/etc/postfix/user_whitelists/${sender}, reject

# Then in master.cf
submission inet n - n - - smtpd
  -o smtpd_restriction_classes=user_whitelist
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject_unauth_destination

Create individual whitelist files for each user in /etc/postfix/user_whitelists/

When dealing with large whitelists:

# Use indexed databases for better performance
whitelist_db_type = hash

# Cache lookups for better performance
smtpd_recipient_restrictions = 
    ...
    check_recipient_access proxy:btree:$data_directory/whitelist_cache
    ...

When configuring Postfix as a restricted mail gateway, many administrators discover that smtpd_recipient_restrictions alone won't prevent outbound delivery to non-whitelisted addresses when using sendmail or Postfix's sendmail compatibility interface. This occurs because these submission methods bypass SMTP-level restrictions.

To properly enforce recipient whitelisting, we need to implement restrictions at both the SMTP and submission levels:

# main.cf
smtpd_recipient_restrictions =
    reject_unauth_destination
    check_recipient_access hash:/etc/postfix/whitelist_recipients

smtpd_relay_restrictions =
    permit_mynetworks
    check_recipient_access hash:/etc/postfix/whitelist_recipients
    reject

# Critical for sendmail interface
default_destination_recipient_limit = 1

Create your whitelist file (e.g., /etc/postfix/whitelist_recipients) with format:

# Whitelist format
allowed@domain.com  OK
@trusted-domain.com OK  # Domain-wide permission

Then process it with:

postmap /etc/postfix/whitelist_recipients
systemctl reload postfix

For sendmail submissions, add to master.cf:

# Override default pickup service
pickup    fifo  n       -       n       60      1       pickup
  -o content_filter=
  -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks
  -o smtpd_restriction_classes=whitelist_only
  -o smtpd_recipient_restrictions=check_recipient_access hash:/etc/postfix/whitelist_recipients,reject

Verify with these commands:

# Test SMTP restriction
telnet localhost 25
MAIL FROM:<test@example.com>
RCPT TO:<non-whitelisted@domain.com>  # Should reject

# Test sendmail restriction
echo "Test" | sendmail -f test@example.com non-whitelisted@domain.com

For more granular control with LDAP or MySQL:

smtpd_recipient_restrictions =
    reject_unauth_destination
    check_client_access ldap:/etc/postfix/ldap-sender-groups.cf
    check_recipient_access ldap:/etc/postfix/ldap-whitelist.cf
    reject

Where ldap-whitelist.cf contains your LDAP query logic for authorized recipients.