Amaury.net
Accueil Liste articles Forum Ma liste de cadeaux Contact

Dédibox (2) : DDOS

29 décembre 2006

Voici la suite de mes aventures avec mon serveur Dédibox.

J'ai un petit problème : je me prends depuis quelques semaine un DDOS. Un très grand nombre de connexions sont faites depuis plusieurs adresses IP, cherchant toutes à se conencter sur le port 80 (serveur Web).

Pour être exact, les logs Apache me disent plusieurs choses :

  • Le user-agent utilisé pour toutes ces connexions est "Maxthon".
  • On dirait que les requêtes essayent de craquer une session de forum PHPBB, sûrement pour pouvoir déposer des spams sur des forums.

Après une petite recherche sur le Net, j'apprends que Maxthon est un navigateur Web alternatif, basé sur Internet Explorer. Entre autre particularités, il propose un truc un peu bizarre : le fait de pouvoir contrôler son navigateur à distance. Je ne vois pas bien l'utilité de la chose. Par contre, les hackers/spammeurs l'ont bien comprise et exploitée, et semblent prendre le contrôle de centaines de navigateurs Maxthon, sans que leurs propriétaires ne le sachent, pour effectuer des milliers de requêtes.

Update de novembre 2007 : Je viens de retourner faire un tour sur le site de Maxthon, et - comme c'est bizarre - cette fonctionnalité a disparu. Entre-temps, combien y a-t-il d'anciennes versions installées et non mises à jour, qui sont utilisables par les pirates ? Pfff...

Bref, j'ai trouvé un remède sur une page du site Linux Security :

Dans le fichier /etc/sysctl.conf :

net/ipv4/conf/all/rp_filter=1
net/ipv4/tcp_syncookies=1

Dans le fichier /etc/rc.local, ajouter :

for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
    echo 1 > $f
done
echo 1 > /proc/sys/net/ipv4/tcp_syncookies

Après avoir testé, ça ne marche pas...

Il faut donc trouver une solution. Essayons quelque chose de bourrin : bannir les connexions de toutes les adresses IP avec lesquelles un navigateur Maxthon s'est connecté. Je me suis donc fait un script shell, que je laisse tourner en boucle. Je le lance en root, car ce script parse mes fichiers de log Apache, et ajoute des règles de filtrage dans le firewall, pour bloquer les adresses IP des machines floodeuses.

Je crée le fichier ban_ip.sh :

#!/bin/sh
if [ x$1 == "x-f" ]; then
    echo -n "+++ Reinit firewal..."
    /etc/init.d/firewall
    echo " OK"
    echo -n "+++ Process liste complete "
    for i in `cat /root/ban_ip_list-processed`; do
        if [ x$i != x ]; then
            echo -n "."
            /sbin/iptables -I INPUT -s $i -j DROP
        fi
    done
    echo " OK"
fi
while [ 0 ]; do
    if [ -f /tmp/ban_ip.lck ]; then
        echo "dual exec"
    else
        DEBUT=`date +"%s"`
        touch /tmp/ban_ip.lck
        DEBUT_DATE=`date +"%F %T"`
        grep "SV1; Maxthon" /var/log/apache2/*-access.log  | cut -d \  -f 1 | cut -d \: -f 2 | sort | uniq > /root/ban_ip_list-collected
        for i in `cat /root/ban_ip_list-processed`; do
            grep -v $i /root/ban_ip_list-collected > /root/tmp
            mv /root/tmp /root/ban_ip_list-collected
        done
        cat /root/ban_ip_list-collected | sort | uniq > /root/tmp
        mv /root/tmp /root/ban_ip_list-collected
        SIZE=`wc -l /root/ban_ip_list-collected | cut -d \  -f 1`
        if [ $SIZE -gt 0 ]; then
            echo
            echo -n "$DEBUT_DATE [$SIZE]"
            DEBUT_APACHE=`date +"%s"`
            for i in `cat /root/ban_ip_list-collected`; do
                if [ x$i != "x" ]; then
                    echo -n "."
                    /sbin/iptables -I INPUT -s $i -j DROP
                fi
            done
            cat /root/ban_ip_list-collected >> /root/ban_ip_list-processed
            NBR_WWW=`netstat | grep www | grep -v crawl | wc -l`
            if [ $NBR_WWW -gt 80 ]; then
                /usr/sbin/apache2ctl graceful
            fi
            FIN_APACHE=`date +"%s"`
            DELTA_APACHE=`expr $FIN_APACHE - $DEBUT_APACHE`
            echo -n "($DELTA_APACHE s"
        fi
        rm /root/ban_ip_list-collected
        rm /tmp/ban_ip.lck
        if [ $SIZE -gt 0 ]; then
            FIN=`date +"%s"`
            DELTA=`expr $FIN - $DEBUT`
            echo "/$DELTA s) "
        else
            echo -n "."
        fi
    fi
    sleep 45
done

Au redémarrage du serveur, on peut lancer le script avec l'option "-f", pour forcer le retraitement de toutes les adresses IP qui sont stockées dans le fichier ban_ip_list-processed.
Je conseille de lancer le script en lui affectant une priorité basse, pour qu'il ne risque pas de manger les ressources du serveur :

nice 10 ./ban_ip.sh
 
Lien super intéressant ;-)