How to Configure Postfix to Exclude Local Emails from Relay Host Routing


5 views

When integrating SMTP relay services like SMTP2GO with Postfix, a common challenge emerges: system-generated emails (cron jobs, alerts, etc.) get unnecessarily routed through the external relay. This creates three problems:

  • Unnecessary consumption of SMTP service quotas
  • Potential delivery delays for critical system notifications
  • Violation of SMTP provider's acceptable use policies for automated emails

Your current main.cf shows:

relayhost = [smtpcorp.com]:2525
mydestination = ec2-46-51-151-256.eu-west-1.compute.amazonaws.com, localhost.eu-west-1.compute.internal, localhost

The core issue lies in how Postfix's mydestination and relayhost interact when determining mail routing paths.

1. Explicit Transport Mapping

Create a transport map to override relay behavior for specific domains:

# Add to main.cf
transport_maps = hash:/etc/postfix/transport
local_transport = local

# Create /etc/postfix/transport
ec2-46-51-151-256.eu-west-1.compute.amazonaws.com local:
localhost.eu-west-1.compute.internal local:
localhost local:

# Then run
postmap /etc/postfix/transport
systemctl reload postfix

2. Sender-Based Routing Control

Prevent specific senders from using the relay:

# Add to main.cf
smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/sender_access

# Create /etc/postfix/sender_access
root@ec2-46-51-151-256.eu-west-1.compute.amazonaws.com REJECT

# Then run
postmap /etc/postfix/sender_access
systemctl reload postfix

3. Smart Host Alternative Approach

Conditional relay based on recipient domains:

# Add to main.cf
sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay

# Create /etc/postfix/sender_relay
@ec2-46-51-151-256.eu-west-1.compute.amazonaws.com :
@localhost :

# Then run
postmap /etc/postfix/sender_relay
systemctl reload postfix

After implementing any solution, verify with:

echo "Test local delivery" | mail -s "Local Test" root
tail -f /var/log/mail.log

Look for entries containing status=sent without your relay host's name in the delivery path.

For granular control over system users:

# Create /etc/postfix/recipient_access
root@localhost.localdomain FILTER local:
nobody@localhost.localdomain FILTER local:

# Add to main.cf
recipient_canonical_maps = hash:/etc/postfix/recipient_access

# Then run
postmap /etc/postfix/recipient_access
systemctl reload postfix

When configuring Postfix to use SMTP2GO as a relay host (smtpcorp.com:2525), many administrators encounter an unexpected behavior where local system emails (like cron job outputs) also get routed through the external SMTP service. This creates unnecessary traffic and potential billing issues with your SMTP provider.

Postfix makes routing decisions based on these main configuration parameters:

myhostname = ec2-46-51-151-256.eu-west-1.compute.amazonaws.com
mydestination = ec2-46-51-151-256.eu-west-1.compute.internal, localhost
relayhost = [smtpcorp.com]:2525

The key issue is that your mydestination list doesn't include the FQDN that cron jobs use (ec2-46-51-151-256.eu-west-1.compute.amazonaws.com), causing Postfix to treat them as non-local mail.

Solution 1: Proper mydestination Configuration

Update your /etc/postfix/main.cf:

mydestination = $myhostname, localhost.$mydomain, localhost

This ensures system-generated emails are treated as local delivery.

Solution 2: Transport Map for Selective Routing

Create /etc/postfix/transport:

# Local delivery
ec2-46-51-151-256.eu-west-1.compute.amazonaws.com local:
localhost.localdomain local:
localhost local:

# External relay
* smtp:[smtpcorp.com]:2525

Then compile and activate:

sudo postmap /etc/postfix/transport

Add to main.cf:

transport_maps = hash:/etc/postfix/transport

Solution 3: Sender-Based Routing (Advanced)

For more granular control, use sender_dependent_relayhost_maps:

# /etc/postfix/sender_relay
@localhost.localdomain local:
@ec2-46-51-151-256 local:
root@ local:

Configure Postfix:

sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay

After changes, always test:

sudo postfix check
sudo postfix reload
echo "Test local mail" | mail -s "Local test" root
echo "Test external mail" | mail -s "External test" user@example.com

Check mail logs:

tail -f /var/log/mail.log

For high-volume servers:

  • Set up a local mail alias for root (/etc/aliases)
  • Consider using nullmailer for system messages
  • Monitor your SMTP provider's usage metrics