July 28, 2009
As my first ideas discussed in the first part of this series didn’t work out as I liked it, I went ahead and looked for other means to withstand these waves. If packets and connections should not reach courier, I would need to use a smtp proxy or to something with the Linux kernel. As the OpenBSD spamd is not available for Linux, I looked than through the iptables documentation and found the ipt_recent module.
It provides a userspace interface which enables a script/program to add IP addresses to a list which get them drop/reject for a given time. I thought this is exactly what I need. Why?
I cannot just drop/reject packages of IPs which are in DNS RBL, as maybe there is a false positive and he needs to know that there is a problem. The mail server needs therefore to send a 5xx the first time, but it is quite ok I think to not except connections for him some minutes after this.
This setup should at least give courier time to close the connections within the timeout, and denies a spammer trying to deliver more than one mail, or keep the connection up by ignoring the 5xx. So I went ahead. First I loaded the iptables module with an option to allow more IP addresses stored.
modprobe ipt_recent ip_list_tot=1000
I think 1000 is quite on the low end, as the spam waves easily reach them. Than I added following iptables commands to my firewall script.
# build sub chain
$iptables -N SPAMMER
# move all incomming smtp traffic there
$iptables -A INPUT -p tcp --dport 25 -j SPAMMER
# check if the source ip is already in the list, if so give it another 60 sec and drop the packages
$iptables -A SPAMMER -m recent --name spammer --update --seconds 600 -j DROP
As you can see we drop the packets for 10 minutes. If a packet is send within that 10min the time period starts again.
You can test your setup by doing following.
echo +220.127.116.11 >/proc/net/ipt_recent/spammer
and take a look at
Replace 18.104.22.168 by an IP address of a spammer (just look in your logfile 😉 ) and see it working. Ok, now that we have the kernel/iptables part we need a script which adds the IP addresses of spammers on a DNS RBL after the first 5xx to the ipt_recent list.
As this is only for testing at this point I wrote a small script which watches the mail.log file and looks for 511 errors (the courier error code for DNS RBL hits) and add the IP addresses of the sending servers/zombies to ipt_recent.
Here is the python script: watchForSpammers.py. I don’t go into any details it is quite easy anyway. Start it like this within screen (
apt-get install screen) to keep it alive even after logout.
The script does its work and adds IP addresses to the ipt_recent list which blocks them also nicely. Just type following to verify it.
iptables -L -xvn
You will see a line like this.
Chain SPAMMER (1 references)
pkts bytes target prot opt in out source destination
15213 724935 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 recent: UPDATE seconds: 600 name: spammer side: source
But the big question is, does it help against the spam waves and its length and heights? More No than Yes ;-). It does almost nothing against the height, but it allows courier to go back a little faster to normal. But still my mail server is maxed out.
So I continue to search for another way. Any ideas?