Une gestion avancée de fail2ban

Beaucoup d’articles sont déjà parus sur l’utilisation de fail2ban pour protéger son ordinateur. Je vais parler ici d’une utilisation avancée de fail2ban, couplé avec le pare-feu iptables dans le but de faire plein de joli de choses avec ceux qui tentent d’accéder à nos Pcs!

Pour rappel, fail2ban permet de bloquer certaines IPs en fonction de ce que les logs renvoient comme messages. Il est possible de déterminer les ports sur lesquels les IPs seront bloquées et la durée du blocage. En ce qui concerne les filtres qui déclencheront ou non le blocage, cela se base sur des regex, et on peut déterminer le nombre de tentatives avant qu’un blocage ne soit appliqué.

Dans l’esprit du projet, fail2ban empêche les attaques par force brute, mais nous allons voir qu’il est tout à fait possible de l’utiliser dans d’autres fins.

Créer de nouvelles règles de filtrage

Dans un premier temps, nous allons mettre en place une nouvelle règle de blocage pour, par exemple, bloquer les IPs en fonction des codes d’erreurs d’apache.

Mettre en place une nouvelle règle se fait de manière très simple, il suffit de créer un fichier contenant la regex à appliquer, et de mettre une référence vers ce fichier dans la configuration de fail2ban.

Dans notre cas, pour bloquer les IPs ayant générés une erreur 403 ou une erreur 401 dans apache, notre regex se présentera ainsi:

failregex = :80  .* ".*" 403 = :80  .* ".*" 401

(Celle-ci est bien sûr à adapter en fonction de la manière dont vous affichez vos logs de connexions.)

Dans le fichier de configuration de fail2ban (/etc/fail2ban/jail.conf), nous allons demander la lecture de ce fichier en indiquant quelques paramètres supplémentaires:

[apache-block]
enabled = true #Oui on active
port = http #On ne bloque que le port 80
filter  = apache-block # le nom du fichier que l'on a créé juste avant
action  = %(action_)s
logpath = /tmp/log/apache/access.log
maxretry = 1 #Nombre de tentatives
banaction = iptables-redirect # L'action à appliquer sur l'IP
bantime = 3600 # Le temps pendant lequel l'ip sera bannie.

Créer de nouvelles actions

Une fois que fail2ban aura lancé une procédure de blocage sur une connexion, il va lancer un script contenant les actions à réaliser sur cette IP. D’habitude ce script contient une règle iptables qui bloque l’adresse, et une autre règle qui supprime ce blocage.

Nous allons maintenant jouer avec iptables pour réaliser quelques effets intéressant avec nos IPs à bannir:

Relancer la durée du blocage

Par défaut, fail2ban retire le blocage sur l’IP une fois que la durée spécifiée est écoulée. Je trouve ceci limité car cela n’empêche pas l’attaquant de continuer ses attaques et se retrouver prêt à refaire une attaque dès que cette durée est écoulée. De plus, cela peut donner une information sur la durée pendant laquelle nous filtrons son adresse.

Iptables propose un module, modrecent, permettant de bloquer une IP pendant une durée déterminée, et de réinitialiser cette durée si jamais une nouvelle connexion venait à être réalisée durant cette période.

Pour ceci nous allons devoir une règle iptables, en dehors de fail2ban, qui consistera à bloquer une IP pendant telle période:

Dans fail2ban, nous allons créer un nouveau fichier action, qui se présentera comme suit:

#On crée une nouvelle table
actionstart =   iptables -N fail2ban-<name>
                iptables -A fail2ban-<name> -j DROP
                #On insère une nouvelle règle qui met à jour le compteur à chaques nouvelles tentatives tant que le délai n'est pas écoulé
                iptables -I INPUT -p  <protocol> -m multiport --dports  <port> -m recent --update --seconds 360000 --name fail2ban-- -j fail2ban-<name>

actionstop =    iptables -D INPUT -p  <protocol> -m multiport --dports  <port> -m recent --update --seconds 360000 --name fail2ban-- -j fail2ban-<name>
                iptables -F fail2ban-<name>
                iptables -X fail2ban-<name>

# Pour bannir une IP, il suffit de l'écrire dans le fichier de configuration de mod-recent
actionban =     echo +<ip> > /proc/net/xt_recent/fail2ban-<name>

# On ne retire pas de l'unban, cela se fera tout seul une fois que l'attaquant aura terminé de se connecter
actionunban =

Il nous suffit de l’enregister dans le fichier /etc/fail2ban/action.d/iptables-recent.conf

Si l’on veut bloquer une ip manuellement, il suffit d’éxécuter la dernière ligne, à savoir

# echo  +${IP} > /proc/net/xt_recent/fail2ban-<name>

Mettre un message d’alerte

On peut décider d’annoncer à notre utilisateur bloqué que nous avons banni son IP. Cela peut être utile si nous avons mis en place des règles de filtrage très strictes et qu’un utilisateur peut se retrouver bloqué sans avoir tenté la moindre intrusion (mieux vaut être trop prudent que pas assez)

Pour cela, nous allons avoir besoin d’un service qui consistera à afficher le texte sur demande. Hors de question de demander ça à apache ou autre serveur web, nous allons mettre en place notre propre serveur web, qui présentera une page statique, toujours identique.

Socat et tout désigné pour cela. Dans notre exemple nous allons le faire tourner en tant que serveur, sur un port ouvert, et avec des droits limités. Notre règle iptables consistera juste à rediriger les connexions entrantes sur le port 80 vers le port où l’on fait tourner socat.

sudo -u nobody socat tcp4-listen:6666,reuseaddr,fork exec:"cat /etc/apache2/banned.html" &

et la règle iptables à mettre en place:

#On crée la règle sur la table de préroutage :
actionstart = iptables -t nat -N fail2ban-<name>
iptables -t nat -A fail2ban-<name> -j RETURN
iptables -t nat -I PREROUTING -p  <protocol> -m multiport --dports <port>-j fail2ban-<name>

iptables -N fail2ban-<name>
iptables -A fail2ban-<name> -j RETURN
iptables -I INPUT -p   <protocol> -m multiport --dports   <port> -j fail2ban-<name>

et pour lancer l’action, là encore, on simule une perte de paquet pour ralentir le temps d’affichage de la page

actionban =  iptables -t nat -I fail2ban-<name> 1 -s  -p tcp -m multiport --dports  <port> -m statistic --mode nth --every 3 -j REDIRECT --to-port 6666
iptables -I fail2ban-<name> 1 -s  -j DROP

Les règles d’unban et de stop se font en symetrique de ban et start, en supprimant des règles crées.

Utiliser les nouvelles règles

Cela se fait simplement en utilisant les nouveaux noms de fichier à la place des anciens. Dans le fichier /etc/fail2ban/jail.conf, il suffit d’utiliser la directive:

banaction = iptables-recent

pour utiliser les nouvelles directives à la action de filtrage.

Voilà, cela permet de mettre en place une sécurité personnalisée et adaptée, qui sort déjà des outils et configuration standards (ce qui est toujours une bonne chose en matière de sécurité). Les exemples que j’ai donnés ne sont que des suggestions, et il est possible de faire beaucoup d’autres choses avec un peu d’imaginations. Je vous renvoie au manuel d’iptables qui présente la liste de tous les modules existants, et de regarder un peu les paramètres disponibles parmi les fichiers de configuration de fail2ban. Mon seul regret est qu’à ce jour, ce programme ne gère pas encore les Ip en v6, mais ça n’est - pour l’instant - pas encore critique..