Spammers really annoy me.
It’s become a bit of a hobby for me. I recently installed amavisd-new which has been quite excellent. My major concern is that spammers are still connecting to my mail server and wasting my resources – even if they do get rejected or bounced.
Even worse – they’re ignoring the 5xx rejection messages generated by Postifx and it’s RBL list. I’ve had spammers over the last few weeks connecting once a minute even though they recieve a permanent error!
So, I put my Hat of Thought on and came up with a better solution.
Why not monitor the Linux maillog for the “554 Service Unavailable” messages and firewall hosts that keep on trying?
I’m not much of a coder, but I’ve hacked together a little perl script that does just that. What I’d REALLY like now, is for someone with more coding capability than me to polish it up a bit, maybe remove the system call, add a logging mechanism and make the entries such that they expire after a definable period.
Please let me know if you use the script as I’d love to talk to other spam warriors.
#!/usr/bin/perl
$thresh = 2; # how many times the spam host can try before they are blocked
$interval = 1; # check the maillog every x seconds
$logfile = "/tmp/spamslam.txt";
use File::Tail;
$file = File::Tail->new( name => '/var/log/maillog', maxinterval => $interval );
while ( defined( $line = $file->read ) ) {
if (
$line =~ m/554 Service unavailable/
&&
$line =~ m/(d{1,3}.d{1,3}.d{1,3}.d{1,3})/
)
{
push @slamlist, $1;
foreach $ip (@slamlist) {
if ( $ip =~ m/$1/ ) {
@count = grep( /$ip/, @slamlist );
foreach $xi (@count) { $attempts++; print "$ip: $attemptsn"; }
if ( $attempts == $thresh ) {
# iptables -I INPUT inserts the rules at the top of the INPUT ruleset
system("/sbin/iptables -I INPUT -s $ip -j DROP");
my ($sec, $min, $hour, $mday, $mon, $year) = localtime(time);
printf "%4d-%02d-%02d %02d:%02d:%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec;
print " - $ip firewalled.n";
open OUTPUT, ">> $logfile" or die "Unable to open $logfile:$!n";
printf OUTPUT "%4d-%02d-%02d%02d:%02d:%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec;
print OUTPUT " - $ip firewalled.n";
close OUTPUT;
@slamlist = grep( !/$ip/, @slamlist );
}
}
@count = ();
$attempts = 0;
}
}
}
Good Luck!
Download file