EXIM4 No Junk Mail

How I Beat the Bots with Exim4 Rate Limiting and an Auto-Ban Firewall Script

created April 25, 2025, last updated April 25, 2025.

.

Introduction

Email servers are constant targets for bots: spam attempts, relay tests, fake login floods.
When I noticed a huge increase in spam and attack attempts on my Exim4 mail server, I decided to fight back โ€” properly.

In this post, I’ll show you how I:

  • ๐Ÿงน Cleaned up my Exim4 logs
  • ๐Ÿšซ Rate-limited abusive IPs at the SMTP level
  • ๐Ÿ”ฅ Automatically blocked offenders at the firewall level
  • ๐Ÿ–ฅ๏ธ Built a slick web dashboard to monitor everything in real-time

The result: The bots gave up and moved on. My server is calm, responsive, and fully protected.

Step 1: Activate Exim4 Rate Limiting

Exim4 has powerful built-in ratelimit features. I added a simple rule to my acl_check_rcpt ACL:

deny
  ratelimit = 10 / 1h / strict
  message = Too many messages, try later
  log_message = Rate limited: $sender_host_address
  
  • Limit: Max 10 messages per hour per IP.
  • Strict: Every violation resets the timer.
  • Logging: Every rate-limited IP gets logged.

Suddenly, bots hammering my server were getting temporary rejections like:

“Too many messages, try later.”

And all rate-limited attempts were logged in /var/log/exim4/mainlog.

Step 2: Harvest Offenders Automatically

I wrote a simple script to extract IPs from the Exim log:

docker exec -i mail_exim4_1 tail -n 1000 /var/log/exim4/mainlog \
  | grep 'Rate limited:' \
  | awk '{print $NF}' \
  | sort | uniq -c | awk '$1 >= 3 { print $2 }' \
  > /tmp/exim-rate-limited-ips.txt
  

This gave me a clean list of serious offenders.

Step 3: Block Them at the Firewall

I used ipset and iptables to ban these IPs at the host level:

sudo ipset create ratelimited hash:ip timeout 86400 -exist

while read ip; do
    sudo ipset add ratelimited "$ip" timeout 86400 -exist
done < /tmp/exim-rate-limited-ips.txt
  

Then inserted a firewall rule into the Docker-specific DOCKER-USER chain:

sudo iptables -I DOCKER-USER 1 -m set --match-set ratelimited src -j DROP
  

Effect: As soon as an IP hit my server after being rate-limited by Exim, it was instantly dropped at the firewall, before it could even touch my containers.

Step 4: Build a Status Dashboard

To keep an eye on things, I built a dynamic HTML dashboard showing:

  • Number of IPs currently blocked
  • Number of packets dropped
  • Top offending IPs
  • Auto-refresh every 30 seconds

Result: Victory

After about 24 hours:

  • Spam attempts dropped to almost zero
  • Bots kept getting blocked instantly
  • The attackers finally gave up and went away

My Exim4 server runs lighter and faster than ever, with completely clean mail logs.

Conclusion

Sometimes, you don’t need complex external tools or expensive firewall appliances.

Exim + Linux + a bit of scripting = total control.

If you’re running your own mail server, I highly recommend setting up something like this.
It’s simple, effective, and once configured, it needs almost no babysitting.

Bots only win if you let them. ๐Ÿ›ก๏ธ

Comments

This site uses Akismet to reduce spam. Learn how your comment data is processed.