Mes passions, le boulots, mes coups de gueule...




Fail2Ban : Bannir des IP signalées par AbuseIPDB

Categorie : Geek, Informatique, Linux, Raspberry Pi · par 14 Avr 2018

Introduction

Malgré l’utilisation de Fail2Ban et de listes d’IP à bannir, mon Raspberry Pi subit encore des ralentissements dû  à des connexions indésirables qui utilisent beaucoup de ressources, principalement PHP.

J’ai donc décidé de vérifier régulièrement l’IP des utilisateurs connectés sur le port 443 et de la comparer à une base de données en ligne.

AbuseIPDB

Présentation

Il existe différentes bases de données regroupant ce genre d’IP qui ont présenté un comportement « abusif » par le passé.

J’ai choisi d’utiliser AbuseIPDB.com car le service offre une API simple à configurer dans un script.

Inscription

Pour utiliser l’API, il faut s’inscrire sur le site, puis, se rendre dans la section « API Key » pour copier la clef.

Fail2Ban

Jail

Pour configurer Fail2Ban, nous allons éditer le fichier /etc/fail2ban/jail.conf :

$ sudo nano /etc/fail2ban/jail.conf

Dans la partie # JAILS, nous allons ajouter ces lignes :

[banabuseip]

enabled = true
filter = banabuseip
action = iptables-multiport[name=BanAbuseIP, port="80,443,110,995,25,465,143,585,993,587,21,22", protocol=tcp,udp]
logpath = /var/log/banabuseip.log
maxretry = 1
bantime = 86400
# 86400 = 1 jour

Dès qu’une IP sera ajoutée, elle sera bannie durant 24h pour les ports et les protocoles indiqués.

Filtre

Nous allons créer un filtre dans /etc/fail2ban/filter.d/banabuseip.conf :

$ sudo nano /etc/fail2ban/filter.d/banabuseip.conf

Nous ajoutons ces lignes au fichier :

#
# Filtre BanAbuseIP
#
[Definition]
failregex = 
ignoreregex =

Logs

Nous allons ensuite créer un fichier de logs vide nécessaire au bon fonctionnement de Fail2Ban :

$ sudo touch /var/log/banabuseip.log

Le script

Maintenant que tout est en place, il ne nous reste plus qu’à créer le script bash :

$ sudo nano /home/pi/scripts/BanAbuseIP.bash
#!/bin/bash

# Vérifie que l'on est en Root
if [[ $EUID -ne 0 ]];
then
    echo "Ce script doit être exécuté avec les privilèges administrateur"
    exit 1
fi

AbuseIPDB_API_key=IciLaClefAbuseIPDB
White_IP1="192.168" # IP du réseau local
White_IP2="104.31" # IP de CloudFlare qui héberge AbuseIPDB : https://www.lookip.net/ip/104.31.74.222

my_array=( $(netstat -tn 2>/dev/null | grep :443 | awk '{print $5}' | cut -d: -f1 | sort | uniq | sort -nr | head) )

for ip in ${my_array[@]};
do
    echo $ip
    if [[ $ip == $White_IP1* ]] || [[ $ip == $White_IP2* ]] # IP locale et CloudFlare blanchies
    then
        echo "$(tput setaf 3)L'adresse a été dédectée comme imblocable.$(tput setaf 7)"
    else
        curl_result=$(timeout -s SIGINT 3s curl -s "https://www.abuseipdb.com/check/$ip/json?key=$AbuseIPDB_API_key")
        if [ "$curl_result" == "[]" ] ;
        then
            echo "$(tput setaf 2)Cette IP n'a pas été reportée par AbuseIPDB.$(tput setaf 7)"
        else
            wget_result=$(timeout -s SIGINT 3s wget -q -O - https://www.abuseipdb.com/check/$ip)
            conf_abuse=$(echo $wget_result | grep -o -P '(?<=Confidence of Abuse is <b>).*(?=%</b>:)')
            if [ $conf_abuse -le 30 ]
            then
                echo "$(tput setaf 3)L'adresse a été reportée par AbuseIPDB à seulement $conf_abuse%.$(tput setaf 7)"
            else
                echo "$(tput setaf 1)Cette IP a été bloquée car reportée par AbuseIPDB à $conf_abuse%.$(tput setaf 7)"
                fail2ban-client set banabuseip banip $ip > /dev/null
            fi
        fi
    fi
    echo
done

Le script va stocker toutes les IP connectées au port 443 dans un tableau.

Il va ensuite comparer chaque IP du tableau avec la base de données AbuseIPDB grâce à la commande curl.

timeout -s SIGINT 3s va empêcher le script de se bloquer si la commande ne répond pas :
Ex. Si la connexion internet est coupée.

  • On vérifie si l’adresse est locale 192.168.xxx.xxx ou est celle d’AbuseIPDB cahée derrière CloudFlare 104.31.xxx.xxx
    • Si c’est le cas, on le dit en orange.
    • Si ce n’est pas le cas, on vérifie si le résultat est vide [].
      • Si c’est le cas, c’est que l’IP est OK et on l’inscrit en vert.
      • Si ce n’est pas le cas on charge la page web d’AbuseIPDB et on extrait le pourcentage de confiance dans les résultats remontés.
        • Si le résultat est < 30% on l’indique en orange.
        • S’il est > 30% on bannit l’IP et on l’inscrit en rouge.

Autre solution

Si on ne veut pas utiliser Fail2Ban, il est possible d’utiliser directement IPTables.

On remplace alors la ligne :

fail2ban-client set banabuseip banip $ip > /dev/null

Par celle-ci :

iptables -I INPUT -s $ip -j DROP > /dev/nul

Rendre exécutable

Pour rendre le script exécutable :

$ chmod u+x /home/pi/scripts/BanAbuseIP.bash

Cron

On va automatiser l’exécution du script avec cron :

$ sudo crontab -e

Et on ajoute ces lignes :

# Banit les IP repérées par AbuseIPDB
# Répétition toutes les 3 minutes
*/3 * * * * sudo /home/pi/scripts/BanAbuseIP.bash > /dev/null 2>&1

Le script sera exécuté toutes les 3 minutes.
Modifiez la période en fonction du nombre de requêtes qui seront effectuées par jour.
AbuseIPDB en permet maximum 3000 par jour.

Laisser un commentaire