How to Temporarily Suspend Outbound Mail Delivery to Specific Domains in Postfix with Transport Maps


6 views

When managing a Postfix mail server, there are legitimate scenarios where you might need to temporarily pause delivery to specific domains while maintaining normal operations for others. Common use cases include:

  • Rate limiting during bulk sending to avoid being flagged as spam
  • Temporary troubleshooting of delivery issues
  • Preventing mail loops from misconfigured destinations
  • Compliance with receiving server's temporary requests

Postfix's transport_maps feature provides the most flexible solution for this requirement. The basic concept involves:

# Example transport map entry
gmail.com     sleep:24h
hotmail.com   defer
problemdomain.com   error:4.7.1 Temporary delivery suspension

Here's how to implement temporary suspension properly:

# 1. Edit main.cf
sudo nano /etc/postfix/main.cf

# Add or modify these lines:
transport_maps = hash:/etc/postfix/transport
default_transport = smtp
local_transport = local
relay_transport = relay
# 2. Create/edit transport file
sudo nano /etc/postfix/transport

# Add domain restrictions (one per line):
gmail.com     defer: Temporary delivery suspension
*.hotmail.com slow:5
# 3. Postmap and reload
sudo postmap /etc/postfix/transport
sudo systemctl reload postfix

For more granular control, consider these variations:

# Defer with custom SMTP code
yahoo.com defer_code 451 4.3.5 "Temporary system problem"

# Rate limiting per domain
aol.com slow:2  # 2 messages per second maximum

# Time-based suspension (requires additional scripting)
# Combine with cron jobs for automated enable/disable

When implementing temporary suspensions:

  • Monitor queue growth: mailq | grep gmail.com
  • Set appropriate queue lifetimes in main.cf
  • Consider splitting large queues before resuming delivery
# Verify transport map is working:
postmap -q gmail.com hash:/etc/postfix/transport

# Check Postfix logs:
tail -f /var/log/mail.log | grep transport

# Test configuration:
postfix check
postconf -n

Postfix's transport map feature provides the most straightforward solution for temporarily suspending delivery to specific domains. Here's how to implement this:

# /etc/postfix/transport
gmail.com       defer:[gmail.com]
hotmail.com     smtp:[hotmail.com]:25
*               smtp:

Then update your main.cf:

# /etc/postfix/main.cf
transport_maps = hash:/etc/postfix/transport
default_transport = smtp

For more sophisticated time-based suspension, create a wrapper script that modifies the transport map:

#!/bin/bash
# suspend_domain.sh
DOMAIN=$1
HOURS=$2

echo "$DOMAIN       defer:[$DOMAIN]" >> /etc/postfix/transport
postmap /etc/postfix/transport
postfix reload

# Set up automatic re-enable
(sleep ${HOURS}h && 
 sed -i "/$DOMAIN.*defer/d" /etc/postfix/transport &&
 postmap /etc/postfix/transport &&
 postfix reload) &

When suspending delivery, remember that messages will accumulate in the queue. Monitor queue size with:

postqueue -p | grep -c "$DOMAIN"

To temporarily hold all messages for a domain without deferring:

# /etc/postfix/transport
problem.com     hold:[problem.com]

If you need more granular control than complete suspension, consider rate limiting:

# /etc/postfix/main.cf
sender_dependent_default_transport_maps = hash:/etc/postfix/transport_rates

# /etc/postfix/transport_rates
@gmail.com     slow
@hotmail.com   medium

# Define the transports
slow    unix  -       -       n       -       -       smtp
    -o smtp_destination_rate_delay=60s
medium  unix  -       -       n       -       -       smtp
    -o smtp_destination_rate_delay=5s