Droper les réseaux indésirables avec Netfilter et SpamHaus
Par Julien Vehent le vendredi, août 21 2009, 18:16 - Debian - Lien permanent
Un peu de bidouille netfilterienne pour bloquer les réseaux définit par spamhaus comme indésirables. On pourrait faire cela avec ipset, puisque l'outil est désigné pour, mais apparemment, il faut jouer un peu avec le noyau et recompiler iptables pour avoir une version qui marche sur Lenny.
Du coup, j'ai trouvé que ca aller plus vite de le faire directement dans netfilter, avec quelques lignes de bash.
L'idée est simple: on prend toutes les NOUVELLES connections entrantes et on les fait passer une fois par une chaine spéciale qui va vérifier que l'IP source n'est pas listée par spamhaus. Donc il nous faut cette chaine spéciale et un petit script qui va, tous les matins, récupérer la nouvelle liste de spamhaus et l'intégrer dans netfilter.
C'est parti.
Dans un premier temps, on va créer deux chaines : une CHECKDROPLIST qui va contenir les réseaux et une LOGCHECKDROPLIST qui va loguer avant de DROPer les paquets.
iptables -N CHECKDROPLIST
iptables -N LOGCHECKDROPLIST
iptables -A LOGCHECKDROPLIST -j LOG --log-prefix \
"SOURCE IN DROPLIST" --log-level debug
iptables -A LOGCHECKDROPLIST -j DROP
Pour le moment, on a rien mis dans CHECKDROPLIST, ca va venir après.
Maintenant, il faut que l'on filtre les paquets entrant. Mais ou ? En fait, cela dépend de l'utilisation que vous faites de la machine. Dans mon cas, je n'effectue pas de routage, et donc la chaine FORWARD n'est pas utilisée. Je vais donc pouvoir filtrer simplement dans la table "filter" de la chaine "INPUT".
Pour un récapitulatif des tables et chaines, voir ici : http://wiki.linuxwall.info/doku.php?id=ressources:dossiers:advanced_networking:1_netfilter_en_grand
Dans ma chaine INPUT, j'ai tout d'abord une règle pour accepter les connections ESTABLISHED, et juste après je vais ajouter ma règle de check de la droplist. Encore après, je peux positionner toutes mes règles de filtrage classiques.
La règle de filtrage ne va s'appliquer que sur les états NEW, pour pas alourdir le filtrage et impacter les perfs :
iptables -t filter -A INPUT -i eth0 ! -s 192.168.1.0/24 \
-m state --state NEW -j CHECKDROPLIST
OK, on est pret ! La configuration actuelle ne va pas perturber le fonctionnement normal du firewall, les nouvelles connections vont juste passer dans CHECKDROPLIST et comme rien n'y est fait pour le moment, vont continuer leurs chemin.
Maintenant, le script que l'on va mettre en place va récupérer le fichier sur spamhaus.org, le parser et injecter les adresses dans la chaine CHECKDROPLIST. On va faire passer ces adresses dans une regex pour éviter d'injecter n'importe quoi.
#! /bin/sh
# get the drop list from spamhaus
# and import it into netfilter
URL=http://www.spamhaus.org/drop/drop.lasso;
DEST=/root/droplist/drop.lasso.`date +%s`
wget $URL -O $DEST
IPT=/sbin/iptables
if [ -e $DEST ]
then
# drop existing set of rules
$IPT -F CHECKDROPLIST
# add new rules
for i in `cat $DEST | awk {'print $1'}|\
grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]\
{1,3}\.[0-9]{1,3}\/[0-9]{1,2}$"`
do
$IPT -A CHECKDROPLIST -s $i -j LOGCHECKDROPLIST
done
fi
La regex pourrait être améliorée mais j'ai pas trop eu le temps de la paufiner (avis aux amateurs).
Je vous laisser tester ça chez vous. Au jour d'aujourd'hui, ça m'importe 158 réseaux dans la chaine CHECKDROPLIST. Je vais laisser tourner ça quelques jours puis je m'attarderais sur les stats pour voir si ya vraiment un intérêt à bloquer ces réseaux.
.
