Thursday, September 24, 2009

Hitting back at spammers

I manage a network of servers that include mail servers, web services, and file sharing and I have been doing so for a number of years. One of the most prevalent maintenance issues for me has always been dealing with spammers. These guys have no respect for the general rules and will insist on sending their crap to you even if you are very specific about not wanting it. The thing with spam is that it is not just an email problem. When a spammer slams an email server with millions of bogus messages, often to bogus accounts, it takes a huge toll on the firewall, spam and antivirus processors, and can seriously degrade overall network performance. Simply sending back a "550 - no such mailbox" message only adds to the network traffic and encourages them to try a different mix of fake addresses.

So say goodbye to "Mr. Nice Guy", I am taking the gloves off and delivering an uppercut right to the jaw. I recently wrote a chunk of batch script to identify the hard core spammers who waste all my system resources and just drop their connections cold. This way they will still hit my firewall for a while, but when they realize the server effectively no longer exists, they will take my IP off their list and I will be free of the annoyance.

How does it work? It's really pretty simple. Here is an an example from a Sendmail server I am still using. When one of those annoying people connect to my server, one of the first things they do is check to see if I'll relay mail so it can turn me into a zombie mailer... not gonna happen bud. What ends up happening is that my logs fill up with this garbage:
Sep 24 21:37:20 mairs sendmail[17608]: ruleset=check_relay, arg1=[114.238.85.247], arg2=114.238.85.247, relay=[114.238.85.247], reject=550 5.7.1 Fix reverse DNS for 114.238.85.247,or use your ISP server
Sep 24 21:37:37 mairs sendmail[17610]: ruleset=check_relay, arg1=[190.213.91.165], arg2=190.213.91.165, relay=[190.213.91.165], reject=550 5.7.1 Fix reverse DNS for 190.213.91.165,or use your ISP server
Sep 24 21:38:34 mairs sendmail[17612]: ruleset=check_relay, arg1=[123.17.228.211], arg2=123.17.228.211, relay=[123.17.228.211], reject=550 5.7.1 Fix reverse DNS for 123.17.228.211,or use your ISP server

The cool think about this is that regardless of what hostname they are trying to spoof, the originating IP address is right there for me to grab and use against them. So that is exactly what I did... I wrote a script to pass through my daily logs, pick out the IP addresses on these offending lines, and add them to my firewall rules with a silent "DROP". They never get any feedback, not even a ping response, so to them, the server is dead - a non existent IP.

In the first day, it dropped my spam volume to about a quarter and now it is virtually non-existent. The 30 or 40 spam messages a day I get now are nothing compared to the hundreds of thousands that were filling my logs 2 weeks ago.

Here is the actual script in case you want to run it on your own server. This was built for a CentOS 5.3 i386 server - make the appropriate adjustments for your platform. This should be run on a cron daily just before the log rotation. Alternately you could run it just after log rotation and alter the script to read maillog.1.

The /etc/cron.d job:
45 23 * * * root /home/tmairs/spamkiller >/dev/null 2>&1

The script:
#!/bin/bash

# get list of spammer IP addresses and save to temporary file

exec cat /var/log/maillog | grep check_relay | awk '{ print $8 }' | sort | uniq > /tmp/spammerlist

fname=/tmp/spammerlist

# read file sequentially

while read line
do
# pick off the first address

badaddr=${line/,/}
badaddr1=${badaddr/arg2=/}

# add a rule to drop them at the firewall

exec /sbin/iptables -A INPUT -s ${badaddr1} -j DROP | echo

# loop till it's done.
done <$fname

# save the new IP tables config

exec /sbin/iptables-save

# kill the temp IP file

exec rm /tmp/spammerlist -f

# end




No comments: