On our CentOS server running Postfix with Virtualmin/Webmin management, we've encountered a common but frustrating scenario: a single user sending bulk emails (thousands at once) causes the entire mail server to become unresponsive. This creates a domino effect where other users' emails get delayed or fail entirely while the queue processes the massive batch.
Postfix offers several mechanisms to control email sending rates. The most relevant for our case is the smtpd_client_message_rate_limit
and anvil_rate_time_unit
parameters. However, these typically apply globally. We need user-specific controls.
# Global rate limiting example (not user-specific) smtpd_client_message_rate_limit = 100 anvil_rate_time_unit = 60s
For user-specific limits, we'll combine Postfix's check_sender_access
with custom lookup tables. Here's how to implement it:
# In main.cf smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/sender_limits, permit_mynetworks, reject_unauth_destination # Create the sender_limits file echo "problemuser@domain.com REJECT You are sending too many emails" > /etc/postfix/sender_limits postmap /etc/postfix/sender_limits
For advanced rate limiting, consider installing policyd-rate (now called opendkim-rate-limit):
# Installation on CentOS yum install perl-LDAP perl-IO-Socket-SSL wget https://github.com/porche/policyd-rate/archive/master.zip unzip master.zip cd policyd-rate-master cp policyd-rate.conf /etc/ cp policyd-rate /usr/local/bin/
Then configure Postfix to use it:
# In main.cf smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, check_policy_service inet:127.0.0.1:10031
To prevent one user from affecting others, implement these additional measures:
# Limit concurrent connections per sender default_process_limit = 100 smtpd_client_connection_count_limit = 10 smtpd_client_connection_rate_limit = 30 # Queue management qmgr_message_active_limit = 1000 qmgr_message_recipient_limit = 1000
Since you're using Virtualmin, you can also set these limits through the web interface:
- Go to Server Configuration → Postfix Mail Server
- Under "SMTP Restrictions", add custom rules
- Use "Per-User Message Rate Limit" option
Set up monitoring to catch abuse early:
# Simple monitoring script #!/bin/bash QUEUE=$(mailq | grep problemuser@domain.com | wc -l) if [ "$QUEUE" -gt 500 ]; then echo "Warning: problemuser has $QUEUE emails in queue" | mail -s "Postfix Alert" admin@domain.com fi
On our CentOS server running Postfix with Virtualmin/Webmin management, we encountered a critical issue where a single user sending bulk emails (thousands at once) caused the entire mail server to become unresponsive. This created a domino effect where other users' emails were delayed or failed during queue processing.
Postfix provides several mechanisms to control email sending rates. The most relevant for our case is the smtpd_client_message_rate_limit
and anvil_rate_time_unit
parameters. Here's how to implement user-specific throttling:
# In /etc/postfix/main.cf smtpd_client_message_rate_limit = 100 anvil_rate_time_unit = 60s default_process_limit = 100
For more granular control, we can use Postfix's sender-dependent rate limiting. Create a file called /etc/postfix/sender_ratelimit
:
problemuser@domain.com 10/minute *@domain.com 50/hour
Then add these lines to main.cf
:
smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/sender_ratelimit permit_mynetworks permit_sasl_authenticated reject_unauth_destination smtpd_client_connection_rate_limit = 10
To prevent server overload regardless of user behavior, implement these additional settings:
# Maximum concurrent deliveries default_destination_concurrency_limit = 20 # Maximum recipients per message smtpd_recipient_limit = 1000 # Queue processing control minimal_backoff_time = 300s maximal_backoff_time = 4000s
For proactive management, create a monitoring script that checks queue size and user activity:
#!/bin/bash # monitor_postfix_queue.sh QUEUE_SIZE=$(mailq | grep -c "^[A-F0-9]") MAX_QUEUE=1000 if [ "$QUEUE_SIZE" -gt "$MAX_QUEUE" ]; then # Identify top senders echo "Top email senders:" mailq | awk '/^[A-F0-9]/ {print $7}' | sort | uniq -c | sort -nr | head -10 # Optional: Temporarily throttle the server postconf -e default_destination_concurrency_limit=5 systemctl reload postfix fi
Since you're using Virtualmin, you can also set limits through its interface:
- Go to Webmin → Servers → Postfix Mail Server
- Select "SMTP Authentication and Encryption"
- Set "SMTP client connection rate limit" and "SMTP client message rate limit"
- Apply changes and restart Postfix
After making changes, always verify your configuration:
postfix check postconf -n systemctl restart postfix
These measures should effectively prevent any single user from overwhelming your mail server while maintaining service for others.