Table of Contents
- Introduction
- Understanding Modern Email Attacks
- Initial iRedMail Security Review
- Postfix Hardening
- Dovecot Security
- Firewall Strategy
- Advanced Fail2Ban Configuration
- Automated Subnet Blocking for Mail Services
- Roundcube Webmail Security
- Monitoring and Alerting
- Incident Response
- Conclusion
Introduction
Email servers are prime targets for attackers. This guide focuses on securing iRedMail, a popular open-source mail server solution, against distributed brute force attacks, pre-greet attacks, and automated scanning.
What You’ll Learn:
- Identifying various attack patterns
- Postfix postscreen configuration
- Automated subnet-level blocking
- Monitoring mail server security
- Incident response procedures
Understanding Modern Email Attacks
Types of Attacks We Mitigated
| Attack Type | Pattern | Impact |
|---|---|---|
| SSH Brute Force | Multiple usernames from rotating IPs | Server resource exhaustion |
| Postfix Pre-greet | Data sent before SMTP greeting | Bypasses some filters |
| Distributed Scanning | IP rotation across /24 subnets | Evades single IP bans |
| SMTP AUTH Brute | Password guessing on submission ports | Account compromise |
Real Attack Example
From our logs:
Jun 2 22:56:58 mail postfix/postscreen: PREGREET from [34.77.183.53] Jun 2 22:56:59 mail postfix/postscreen: PREGREET from [34.77.183.53] Jun 2 22:56:59 mail postfix/postscreen: PREGREET from [34.77.183.53]
This attacker sent data before the SMTP greeting, attempting to exploit vulnerabilities.
Initial iRedMail Security Review
Check iRedMail Version
# Check iRedMail version cat /etc/iredmail-release # Check installed packages rpm -qa | grep -E "postfix|dovecot|mysql|php"
Review Default Configuration
# Check all running mail services sudo netstat -tlnp | grep -E ":25|:465|:587|:993|:995|:143|:110" # Expected ports: # 25 - SMTP # 465 - SMTPS # 587 - Submission # 993 - IMAPS # 995 - POP3S # 143 - IMAP (should be disabled) # 110 - POP3 (should be disabled)
Disable Unencrypted Protocols
Edit /etc/dovecot/dovecot.conf:
# Disable plain text protocols protocols = imaps pop3s # Remove imap and pop3 from list
Edit /etc/postfix/master.cf:
# Comment out plain SMTP if not needed # -o smtpd_tls_wrappermode=no
Postfix Hardening
Postscreen Configuration
Edit /etc/postfix/main.cf:
# Enable postscreen postscreen_enable = yes postscreen_bare_newline_enable = no postscreen_bare_newline_action = drop postscreen_non_smtp_command_enable = yes postscreen_non_smtp_command_action = drop postscreen_pipelining_enable = yes postscreen_pipelining_action = drop # DNS Blocklists postscreen_dnsbl_sites = zen.spamhaus.org*2, b.barracudacentral.org*2 postscreen_dnsbl_threshold = 2 postscreen_dnsbl_action = drop # Pre-greet detection postscreen_greet_wait = 6s postscreen_greet_banner = $smtpd_banner postscreen_pregreet_ttl = 30d
SMTP Authentication Hardening
# Limit authentication attempts smtpd_client_connection_rate_limit = 10 smtpd_client_message_rate_limit = 20 smtpd_client_recipient_rate_limit = 20 # Timeouts smtpd_helo_required = yes smtpd_helo_timeout = 5s smtpd_recipient_limit = 100
Header and Body Checks
# Create header check file sudo nano /etc/postfix/header_checks # Add these rules /^Subject:.*Re:.*Re:.*Re:/ DISCARD /^Content-Type:.*multipart\/mixed.*name=".*\.(exe|scr|bat|cmd|com|pif)"$/ DISCARD # Apply in main.cf header_checks = regexp:/etc/postfix/header_checks
Dovecot Security
Authentication Limits
Edit /etc/dovecot/conf.d/10-auth.conf:
# Limit authentication attempts auth_failure_delay = 2 secs auth_username_format = %Lu # Disable plain auth over insecure connections disable_plaintext_auth = yes # Set max authentication attempts mail_max_userip_connections = 10
SSL/TLS Hardening
Edit /etc/dovecot/conf.d/10-ssl.conf:
ssl = required ssl_min_protocol = TLSv1.2 ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256 ssl_prefer_server_ciphers = yes
Connection Limits
# Edit /etc/dovecot/conf.d/20-imap.conf mail_max_userip_connections = 10 # Edit /etc/dovecot/conf.d/20-pop3.conf mail_max_userip_connections = 5
Firewall Strategy
Basic Mail Server Firewall
# Create dedicated zone sudo firewall-cmd --permanent --new-zone=mail sudo firewall-cmd --permanent --zone=mail --add-interface=eth0 # Allow mail ports sudo firewall-cmd --permanent --zone=mail --add-port=25/tcp sudo firewall-cmd --permanent --zone=mail --add-port=465/tcp sudo firewall-cmd --permanent --zone=mail --add-port=587/tcp sudo firewall-cmd --permanent --zone=mail --add-port=993/tcp sudo firewall-cmd --permanent --zone=mail --add-port=995/tcp # Allow SSH (admin access) sudo firewall-cmd --permanent --zone=mail --add-service=ssh # Limit connection rates sudo firewall-cmd --permanent --zone=mail --add-rich-rule='rule service name="smtp" limit value="10/m" accept' sudo firewall-cmd --reload
Blocking Abusive Subnets
# Block entire /24 subnet after detecting multiple attacks sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="34.77.183.0/24" drop' sudo firewall-cmd --reload
Advanced Fail2Ban Configuration
iRedMail-Specific Jails
iRedMail creates several jails automatically. Check them:
sudo fail2ban-client status # Typical iRedMail jails: # - postfix # - postfix-burst # - pregreet # - dovecot # - roundcube # - recidive
Configure Postfix Jail
Edit /etc/fail2ban/jail.d/iredmail.conf:
[postfix] enabled = true maxretry = 3 findtime = 600 bantime = 3600 [postfix-burst] enabled = true maxretry = 10 findtime = 60 bantime = 3600 [pregreet] enabled = true maxretry = 2 findtime = 60 bantime = 7200
Recidive Jail for Persistent Offenders
[recidive] enabled = true logpath = /var/log/fail2ban.log banaction = %(banaction_allports)s bantime = 86400 # 24 hours maxretry = 3 findtime = 86400
Automated Subnet Blocking for Mail Services
The Challenge
Attackers use multiple IPs from the same /24 subnet to avoid traditional bans. Our solution blocks entire subnets automatically.
Postfix Auto-Block Script
Create /usr/local/bin/auto-block-postfix.sh:
#!/bin/bash
THRESHOLD=3 # Block after 3 IPs from same /24
LOG_FILE="/var/log/auto-block-postfix.log"
# Whitelist legitimate email providers (add as needed)
WHITELIST="52.101|40.107|209.85|147.75.180"
# Get banned IPs from mail-related jails
BANNED_IPS=$(sudo fail2ban-client status postfix pregreet 2>/dev/null | \
grep -A1 "Banned IP list" | tail -1 | grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | sort -u)
# Also check recidive
BANNED_IPS="$BANNED_IPS"$'\n'$(sudo fail2ban-client status recidive 2>/dev/null | \
grep -A1 "Banned IP list" | tail -1 | grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
# Process each subnet
echo "$BANNED_IPS" | grep -v '^$' | cut -d. -f1-3 | sort | uniq -c | while read count subnet; do
[ -z "$subnet" ] && continue
# Skip whitelisted providers
if echo "$subnet" | grep -qE "$WHITELIST"; then
echo "$(date): Skipping whitelisted $subnet.0/24" >> $LOG_FILE
continue
fi
if [ $count -ge $THRESHOLD ]; then
if ! sudo firewall-cmd --list-rich-rules | grep -q "$subnet.0/24"; then
echo "$(date): Blocking $subnet.0/24 (detected $count IPs)" | tee -a $LOG_FILE
sudo firewall-cmd --permanent --add-rich-rule="rule family=\"ipv4\" source address=\"$subnet.0/24\" drop"
sudo firewall-cmd --reload
# Clean up individual bans
echo "$BANNED_IPS" | grep "$subnet." | while read ip; do
sudo fail2ban-client unban $ip 2>/dev/null
done
fi
fi
done
Set Up Cron Jobs
# Run every minute sudo crontab -e # Add: * * * * * /usr/local/bin/auto-block-postfix.sh * * * * * sleep 30; /usr/local/bin/auto-block-postfix.sh
Monitoring the Auto-Block Script
bash
# View blocks sudo tail -f /var/log/auto-block-postfix.log # Check current firewall blocks sudo firewall-cmd --list-rich-rules | grep drop
Roundcube Webmail Security
Secure Roundcube Configuration
Edit /var/www/roundcubemail/config/config.inc.php:
// Security settings $config['session_lifetime'] = 30; $config['session_domain'] = '.yourdomain.com'; $config['session_name'] = 'roundcube_session'; $config['cookie_secure'] = true; $config['cookie_httponly'] = true; $config['cookie_samesite'] = 'Strict'; // Login attempts $config['login_rate_limit'] = 3; $config['login_rate_time'] = 5; // Disable dangerous features $config['enable_installer'] = false; $config['enable_spellcheck'] = false;
.htaccess for Roundcube
Create /var/www/roundcubemail/.htaccess:
# Deny access to sensitive files
<FilesMatch "^(config|temp|logs|SQL)">
Order allow,deny
Deny from all
</FilesMatch>
# Limit login attempts
<Limit POST>
Order deny,allow
deny from all
allow from all
</Limit>
Protect admin interface
# Add password protection to /admin
sudo htpasswd -c /etc/roundcube/admin.htpasswd admin
# Add to Apache config
<Directory /var/www/roundcubemail/admin>
AuthType Basic
AuthName "Admin Access"
AuthUserFile /etc/roundcube/admin.htpasswd
Require valid-user
</Directory>
Monitoring and Alerting
Security Status Script
Create /usr/local/bin/mail-security-status.sh:
#!/bin/bash
echo "=========================================="
echo "MAIL SERVER SECURITY STATUS"
echo "Host: $(hostname)"
echo "Time: $(date)"
echo "=========================================="
echo ""
echo "=== FIREWALL ==="
TOTAL=$(sudo firewall-cmd --list-rich-rules 2>/dev/null | grep -c "source address")
echo "Total blocked subnets: $TOTAL"
echo ""
echo "=== FAIL2BAN ==="
sudo fail2ban-client status | grep "Jail list" | sed 's/.*Jail list://' | tr ',' '\n' | while read jail; do
BANS=$(sudo fail2ban-client status "$jail" 2>/dev/null | grep -c "Banned IP list" -A1 | tail -1 | grep -oE "[0-9]+" | head -1)
echo " $jail: $BANS bans"
done
echo ""
echo "=== RECENT ATTACKS ==="
echo "Postfix pregreet (last hour): $(sudo journalctl -u postfix --since '1 hour ago' 2>/dev/null | grep -c 'PREGREET')"
echo "Failed SASL auth (last hour): $(sudo journalctl -u postfix --since '1 hour ago' 2>/dev/null | grep -c 'SASL LOGIN authentication failed')"
echo ""
echo "=== AUTO-BLOCK LOGS ==="
echo "Last 3 blocks:"
sudo tail -3 /var/log/auto-block-postfix.log 2>/dev/null
echo ""
echo "=========================================="
Email Alerts
# Add to crontab for hourly reports 0 * * * * /usr/local/bin/mail-security-status.sh | mail -s "Hourly Mail Security Report" admin@example.com
Centralized Logging (ELK Stack)
# Install Filebeat sudo dnf install filebeat -y # Configure to send to ELK sudo nano /etc/filebeat/filebeat.yml # Add postfix, dovecot, fail2ban logs sudo systemctl enable --now filebeat
Incident Response
When You Detect an Attack
1. Identify the Attack Pattern
# Check recent attacks
sudo journalctl -u postfix --since "10 minutes ago" | grep -E "CONNECT from|PREGREET"
# Identify attacking subnets
sudo journalctl -u postfix --since "1 hour ago" | grep -oE "from \[([0-9]+\.){3}[0-9]+\]" | \
cut -d'[' -f2 | cut -d']' -f1 | cut -d. -f1-3 | sort | uniq -c | sort -rn | head -20
2. Block Immediately
# Manual block of attacking subnet sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="ATTACKING_SUBNET.0/24" drop' sudo firewall-cmd --reload
3. Clear Bans
# Unban all IPs from attacking subnet
sudo fail2ban-client status postfix | grep -o "XX\.XX\.XX\.[0-9]*" | while read ip; do
sudo fail2ban-client unban $ip
done
4. Report Abuse
# Template for abuse report cat << EOF | mail -s "Abuse report from your IP range" abuse@provider.com Dear Provider, Your IP range is being used to attack our mail server. Attacking IPs: [LIST] Time: [TIME] Attack type: [TYPE] Log samples: [SAMPLES] Please investigate. Regards, [Your Name] EOF
Post-Incident Analysis
# Generate attack report
sudo journalctl -u postfix --since "24 hours ago" | \
grep -E "PREGREET|authentication failed" > /tmp/attack-report.txt
# Count unique attacking IPs
grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" /tmp/attack-report.txt | sort -u | wc -l
Conclusion
Your iRedMail server is now hardened with:
- ✅ Postfix postscreen with DNSBL
- ✅ Dovecot authentication limits
- ✅ Automated subnet blocking for distributed attacks
- ✅ Roundcube webmail security
- ✅ Comprehensive monitoring and alerting
- ✅ Incident response procedures
Blocked Subnets Summary
After implementing this guide, your server should have blocked:
- 50+ malicious subnets
- Thousands of attacking IPs
- Multiple hosting providers (Google Cloud, Hetzner, DigitalOcean, etc.)
Final Security Checklist
- SSH key-only authentication
- Firewall rate limiting
- Fail2Ban with recidive jail
- Auto-block scripts running via cron
- Whitelist for legitimate email providers
- Monitoring and alerts configured
- Backup strategy in place
- Incident response plan documented
Resources
Questions about implementing this guide? Leave a comment below or contact our security team.