Kickban! für Spammer
Ich hatte gerade ein wenig Langeweile, kombiniert mit Spaß in den Backen. Was kam raus?
Eine PHP & Shellscript Kombination die Spammer von unserem Server bannt. Dazu habe ich zuerst den Spamfilter des XG-GuildCMS erweitert, so das die Ursprungs-IP eines Spamautors geloggt wird (in die Datenbank). Zusätzlich wird vermerkt wie oft diese IP schon gespammt hat. Als weitere Quelle für zu blockende IPs dient mein Blog hier, dazu wird die IP Adresse des Autoren von Kommentaren abgerufen bei denen Akismet der Meinung ist das es Spam ist.
Dazu habe ich mir zum einen ein kleines Shellskript geschrieben das IPs aus /root/blocked.ips ausliest und diese als DROP Regel in eine eigene iptables Chain ablegt. Dieses Skript ist abgeleitet von dem aus diesem Blogpost.
#!/bin/bash
IPT=/sbin/iptables
SPAMLIST="spamlist"
SPAMDROPMSG="SPAM LIST DROP"
BADIPS=$(cat /root/blocked.ips)
$IPT -N $SPAMLIST
for ipblock in $BADIPS
do
$IPT -A $SPAMLIST -s $ipblock -j LOG --log-prefix "$SPAMDROPMSG"
$IPT -A $SPAMLIST -s $ipblock -j DROP
done
Aber die eigentliche Arbeit erledigt das (CLI-)PHP Skript, es ruft alle IP Adressen aus der XG-GuildCMS Datenbank ab die mehr als 5 mal als Spamautoren „aufgefallen“ sind sowie dasselbe noch einmal für die Kommentare in diesem Blog.
<?php
$dbhost = 'localhost';
$dbuser = '**********';
$dbpass = '**********';
$dbname1 = '**********';
$dbname2 = '**********';
$treshold = 5;
$blacklist = "/root/blocked.ips";
$iptablesChain = "spamlist";
$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ('Error connecting to mysql');
echo "Starting collecting of spam sources for iptables blacklisting (treshold: $treshold) into $blacklist\n\n";
// grab XG-GuildCMS spammer
mysql_select_db($dbname1);
echo "Collecting XG-GuildCMS (www.berserks.org) spammers...\n";
$res = mysql_query("SELECT `ip_adress` FROM `flyff_spamfilter_ips` WHERE `count` > ".$treshold);
while($row = mysql_fetch_array($res)) { $spammerIPs[] = $row['ip_adress']; }
// grab WordPress spammer
mysql_select_db($dbname2);
echo "Collecting WordPress (blog.mcdope.org) spammers...\n";
$res = mysql_query("SELECT `comment_author_IP` AS `ip`, count(`comment_author_IP`) AS `count` FROM `wp_comments` WHERE `comment_approved` = 'spam' GROUP BY `comment_author_IP`");
while($row = mysql_fetch_array($res)) { if($row['count'] > $treshold) { $spammerIPs[] = $row['ip']; } }
if(is_array($spammerIPs) and count($spammerIPs) > 0) {
echo "Finished collection - collected ".count($spammerIPs)." IP addresses, now going to write blacklist file...\n";
$handle = fopen($blacklist, "w");
foreach($spammerIPs as $ip) { fwrite($handle, $ip."\n"); }
fclose($handle);
echo "Dropping old iptables chain and create the updated one...\n";
system("iptables -F ".$iptablesChain);
system("iptables -X ".$iptablesChain);
system("/root/create_antispam_iptables_rules.sh");
echo "Finished!\n\n";
}
mysql_close($conn);
?>
Da WordPress möglicherweise einige Sonderzeichen ruiniert bei der Anzeige hier nochmal beide Scripts zum Download: iptables_skripts.tar.bz2
Das „collect“ Skript ist zwar jetzt sehr speziell, sollte aber für Inspiration sorgen. Getestet ist das ganze bislang nur auf Ubuntu 8.04, sollte aber eigentlich keine Probleme auf anderen Systemen machen.
Update: In dem Code fehlte eine Variable am Anfang des PHP Skripts, im Code oben ist es jetzt ausgebessert. Die Skripte im Download-Archiv enthalten den Fehler noch. Dort muss in Zeile 9 der PHP Datei noch folgendes eingefügt werden:
$iptablesChain = "spamlist";