Filtres et actions personnalisés dans Fail2ban
Sommaire
I. Présentation des filtres et actions de Fail2ban
Nous avons déjà vu dans le premier cours sur Fail2ban comment installer et configurer Fail2ban, nous avons également vu son fonctionnement global ainsi que ses différents fichiers de configuration. Nous allons à présent voir comment créer des filtres et des actions personnalisés dans Fail2ban. Fail2ban est pour rappel un log-based Intrusion Detection System (Système de détection d'intrusion basé sur les logs) et même un IPS Intrusion Prevention System puisqu'il effectue des actions de protection lors d'une détection.
Toute la puissance de Fail2ban réside dans le fait qu'il puisse être adapté à un grand nombre d'outil et de situation, cela est notamment dû à la possibilité de créer des nouveaux filtres et nouvelles actions dans Fail2ban.
II. Rappel sur les filtres et les actions
Il convient tout d'abord de rappeler ce que sont les filtres et les actions dans Fail2ban :
- Filtre : Un filtre dans Fail2ban est une expression régulière qui va être utilisée pour scanner les fichiers de logs ciblés dans nos jails. On applique un filtre sur les nouvelles entrées dans un fichier de logs afin de voir si celles-ci contiennent des informations relevant d'une intrusion ou non. Un filtre n'est rien d'autre que le moyen de détection dont se sert Fail2ban.
Voici un exemple de filtre, celui-ci est présent par défaut dans Fail2ban dans la catégorie des filtres vsftpd (service FTP Linux) :
failregex = vsftpd(?:\(pam_unix\))?(?:\[\d+\])?:.* authentication failure; .* rhost=(?:\s+user=\S*)?\s*$ \[.+\] FAIL LOGIN: Client ""\s*$
Voici à quoi ressemble typiquement une expression régulière, elles sont très utiles ici, car elles permettent d'avoir une précision extrême dans notre filtre. Sans détailler toute l'expression, on recherche ici les échecs d'authentification sur le service FTP. On va donc ici appliquer ce filtre sur un fichier de log du service VSFTPD. Pour avoir plus d'informations sur le fonctionnement basique de Fail2ban, je vous invite à retourner sur le premier cours Fail2ban mis en lien plus haut.
- Action : Une action est tout simplement la ligne de commande, outil ou script qui va être exécuté lorsque les événements le voudront. Typiquement, Fail2ban exécutera une action lorsqu'une ligne de log détectée par nos filtres apparaitra un certain nombre de fois. Les actions peuvent alors être des événements de prévention ou de protections (bannir l'IP en question, redémarrer le service XY, vider le cache de telle application...) ou alors des événements d'alerte (on va envoyer un mail à l'administrateur système, on va générer une alerte dans le système de supervision...).
Voici une action présente nativement dans la configuration de Fail2ban :
printf %%b "Hi,\n The IP <ip> has just been banned by Fail2Ban after <failures> attempts against <name>.\n Regards,\n Fail2Ban"|mail -s "[Fail2Ban] <name>: banned <ip>" <dest>
Ici, il s'agit de l'action d'envoyer un mail lorsque Fail2ban bannit une IP via iptables. Au final, les actions sont de simples commandes comme nous avons l'habitude de les utiliser sous Linux. Leur spécificité vient du fait qu'elles sont lancées par Fail2ban quand certaines conditions sont réunies, ce qui permet une gestion automatique de la protection d'une machine.
Après ce rapide rappel, voyons comment concrètement créer nos propres filtres et actions dans la configuration Fail2ban. Pour suivre ce cours, vous aurez besoin :
- D'un Fail2ban opérationnel
- De notions sur les expressions régulières (très bien documentées sur le net)
III Création d'un filtre personnalisé
Pour rappel, les filtres sont stockés dans /etc/fail2ban/filter.d/, nous allons donc nous y rendre pour créer un nouveau filtre. Chaque filtre est représenté et assigné par son nom dans une configuration de Jail dans Fail2ban. On va donc être attentif au nom que l'on donne à notre filtre.
A. Ajout d'un nouveau filtre Fail2ban
Pour l'exemple du cours, je vais créer un filtre qui va détecter une expression d'un fichier de log totalement fictif, je le nomme "filtre-perso.conf" :
vim filtre-perso.conf
Nous allons maintenant passer à la rédaction de ce filtre. Un filtre sous Fail2ban va contenir une structure prédéfinie que nous allons écrire et détailler ici :
[INCLUDES] before = common.conf [Definition] failregex = ignoreregex =
Le fichier common.conf est inclus sur la plupart des fichiers filtres.
Note : Si vous souhaitez ajouter d'autres filtres déjà existants à votre nouveau filtre, c'est dans la section "[INCLUDES]" qu'il faut le faire. Soit via "before = nom_du_filtre" si l’importation doit avoir lieu avant la déclaration de votre nouveau filtre, soit via "after = nom_du_filtre" si l'importation doit avoir lieu après la déclaration de votre filtre.
On retrouve ensuite la partie "[Definition]" contenant deux champs :
- "failregex =" : Il s'agit des expressions régulières qui vont servir à notre filtre. Toutes les lignes analysées qui correspondront aux filtres mis ici seront susceptibles de déclencher l'action associée dans la jail. Autrement dit, on définit ici ce qu'il faut surveiller.
- "ignoreregex =" : Il s'agit ici des exceptions que l'on souhaite déclarer. Le remplissage de ce champ est optionnel, mais il peut avoir un réel intérêt dans certains cas.
Nous allons maintenant ajouter notre ou nos expression(s) régulière(s). Ici, tout dépend de votre besoin. Pour le contexte du cours, partons sur le cas d'étude suivant :
Je souhaite être alerté à chaque fois que l'outil "dhclient" (permettant la gestion des baux DHCP en tant que client sous Linux) reçoit une IP venant d'un serveur DHCP, je veux au passage récupérer cette IP. J'ai ici un besoin clair, qui peut se traduire dans les logs /var/log/syslog par la ligne suivante :
Dec 20 18:14:13 srvweb01 dhclient: DHCPOFFER from 192.168.1.254
Je vais donc créer un filtre contenant l'expression régulière me permettant de surveiller l'apparition de cette ligne précise dans mes logs. Pour corser un peu les choses, j'ai 3 interfaces sur ma machine 😉 .
Note : Il s'agit ici d'un exemple, la construction de l'expression régulière n'étant pas l'objet de ce cours. Pour créer un filtre personnalisé, je rappelle qu'il faut avoir clairement identifié :
- La ou les ligne(s) de logs que l'on souhaite surveiller
- Le ou les fichier(s) de logs dans lesquel(s) ces lignes seront ajoutées.
Voici donc ce que j'ai mis dans le champ "failregex" de mon nouveau filtre "filtre-perso.conf" :
failregex = .* DHCPOFFER from <HOST>
Ici, quelques explications s'imposent. Notez tout d'abord que mon expression régulière n'est pas complexe du tout, car ce n'est pas le sujet du cours. Si vous souhaitez avoir des exemples plus complexes d'expressions régulières utilisées par Fail2ban, je vous invite à ouvrir les différents filtres présents par défaut qui se trouvent dans /etc/fail2ban/filter.d.
La présence de la chaine "<HOST>" est obligatoire dans un filtre Fail2ban lorsque l'on souhaite récupérer une IP, par exemple pour la renseigner à iptables en vue d'un bannissement temporaire. La chaine "<HOST>" est donc positionnée à l'endroit où sera l'IP dans la ligne de logs filtrée.
B. Test du filtre avec Fail2ban-regex
Une fois votre failregex créé, il est possible de le tester rapidement via la commande "fail2ban-regex". Il faut pour cela disposer d'un fichier possédant une ligne que vous souhaitez filtrer. Voici un exemple :
fail2ban-regex /var/log/syslog.1 /etc/fail2ban/filter.d/filtre-perso.conf /etc/fail2ban/filter.d/filtre-perso.conf
Je sais d'avance que /var/log/syslog.1 contient une ou plusieurs occurrences de la ligne de log que je souhaite surveiller, cela est évidemment nécessaire pour voir si notre regex est valable. Voici le résultat que nous pourrons voir :
On voit ici que mon expression régulière présente dans le nouveau filtre "filtre-perso.conf" a trouvé trois occurrences dans le fichier de log pointé. Dans "Summary", on peut voir également les différentes adresses IP récupérées.
Note : Souvent, lorsque l'expression régulière est fausse ou pas assez précise, Fail2ban-regex affiche des indications pour comprendre ce qui n'a pas fonctionné. Autrement, je vous invite à utiliser des services web en ligne pour peaufiner vos regepx (expression régulière) tels que celui-ci : Test d'expressions régulières en ligne
Une fois notre failregex validée, nous pouvons également y ajouter des exceptions, par exemple si je désire que tous les événements récupérés ayant eu lieu à 21h54 soient exclus, je peux ajouter l'expression suivante dans "ignoreregex" :
ignoreregex = .* 21\:54.* DHCPOFFER from <HOST>
Il faudra ensuite à nouveau utiliser fail2ban-regex pour tester cette nouvelle modification :
fail2ban-regex /var/log/syslog.1 /etc/fail2ban/filter.d/filtre-perso.conf /etc/fail2ban/filter.d/filtre-perso.conf
Note : Attention , il ne s'agit pas d'une erreur. Lorsque l'on souhaite tester et le failregex et l'ignoreregex, il faut bien saisir deux fois le chemin vers le fichier de configuration du filtre.
Ici, on voit alors la section "IgnoreRegex" qui a détecté une occurrence, la seule présentant la chaine "21:54" . Je sais donc que Fail2ban ignorera les lignes ciblées lors de ses vérifications automatiques.
Nous en avons fini avec la création de notre filtre personnalisé, passons maintenant à la création d'une action personnalisée
IV. Création d'une action personnalisée
Comme les filtres, de nouvelles actions peuvent également être configurées dans Fail2ban. Encore une fois, l'utilisation que vous en aurez dépend de votre situation et contexte. La création des actions permet de faire des choses plus complexes que la création d'un filtre, essayons d'appliquer le cas suivant :
Je décide de mettre les IP récupérées par mon filtre précédent dans un fichier /root/infoDHCP.txt.
- A chaque démarrage de Fail2ban, ce filtre sera vidé
- A chaque extinction de Fail2ban, le contenu de ce fichier sera envoyé sur un serveur distant via SSH
- Quand mon filtre-perso détectera une ligne intéressante, elle sera ajoutée dans mon fichier /root/infoDHCP.txt
Cela nous fait de quoi avoir quelque chose d'assez complet, à nos claviers !
On commence par se rendre dans /etc/fail2ban/action.d/, on retrouve alors la même disposition que pour les filtres : des fichiers en *.conf dont le nom sert de référence pour la configuration d'une prison (jail). On crée donc notre action que je nomme dans mon cas dhcp-detect.conf
vim /etc/fail2ban/action.d/dhcp-detect.conf
Ici, on retrouve également une trame de construction commune à toutes les actions, ajoutons-la dans notre nouveau fichier :
[Definition] actionstart = actionstop = actioncheck = actionban = actionunban =
Chacun de ces champs va nous permettre de lancer des actions à différents moments :
- "actionstart" : Il s'agit des commandes qui seront exécutées au démarrage de Fail2ban.
- "actionstop" : Commandes exécutées à l'arrêt de Fail2ban.
- "actioncheck" : Vérification pouvant être opérée avant chaque commande "actionban".
- "actionban" : Action exécutée pour bannir une IP, exécuter l'action principale de protection ou d'avertissement.
Note : Cette "actionban" porte mal son nom. En effet, on se sert ici d'action ban pour effectuer notre action principale lorsqu'un filtre détecte une ligne qui correspond à ses spécifications. Autrement dit, on peut tout mettre dans ce champ pourvu que cela soit une action, et même un script comme nous le verra plus loin. Par exemple, regardez le fichier /etc/fail2ban/action.d/mail.conf, le champ "actionban" y contient une ligne d'envoi de mail, ce qui n'est en rien une ligne de "ban" d'ip...
- "actionunban" : Action exécutée lorsque l'on souhaite "débannir" une IP, utile par exemple quand Fail2ban banni une IP de façon temporaire, là aussi, on peut s'en servir de la façon dont on le souhaite.
Si votre action concerne le bannissement d'un IP ou toute manipulation concernant iptables, il est également nécessaire d'ajouter quelques informations à la suite de la partie "[Definition]" :
[Init] name = defaut port = numero_de_port protocol = tcp_ou_udp chain = INPUT
Voici comment je peux configurer mon fichier dhcp-detect.conf pour qu'il corresponde aux spécifications rédigées plus haut
[Definition] actionstart = echo "" > /root/infoDHCP.txt actionstop = /root/scripts/SendIt.sh actioncheck = actionban = echo <ip> >> /root/infoDHCP.txt actionunban =
Comme je l'ai indiqué, la commande "actionstart" va vider le fichier. Pour le champ "actionstop", on indique un script, c'est une chose intéressante à connaitre, car la possibilité d'utiliser un script rend l'outil encore plus souple et plus puissant. On pourrait d’ailleurs lui envoyer des paramètres, par exemple "/root/scripts/SendIt.sh <ip>". L'action "actionban" va donc écrire l'IP récupérée dans le fichier de log /root/infoDHCP.txt. J'attire ici votre attention sur l’utilisation de "<ip>". Comme pour <HOST> dans les filtres, <ip> est une variable qui permet d'indiquer "l'IP récupérée dans le filtre" facilement.
Nous avons écrit notre filtre ainsi que notre action, nous allons maintenant finaliser le tout en construisant une nouvelle prison (jail) utilisant ces deux nouveaux éléments. Ce sera alors l'occasion de tester leur fonctionnement ! 😉
V. Création d'une Jail à partir d'un filtre/action personnalisé
Le but de ce cours n'est pas de montrer comment configurer une jail dans Fail2ban, néanmoins il est intéressant de montrer comment intégrer des filtres et actions personnalisés dans une jail existante ou une nouvelle jail. Dans le fichier "jail.conf", voici ce qu'il faut ajouter après la ligne
# #JAILS #
On inclut donc la configuration d'une nouvelle prison que je nommerais "dhcp-perso" dans le cadre de ce cours :
[dhcp-perso] enabled = true port = 11111 maxretry = 1 filter = filtre-perso logpath = /var/log/syslog banaction = dhcp-detect
Ici, quelques précisions s'imposent :
- Tout d'abord, le "port = 11111", c'est ici une valeur que j'ai mise au hasard, le champ "port" semble en effet obligatoire. Sinon, cela provoque une erreur au redémarrage de fail2ban. Ne surveillant pas un protocole dans une optique d'action avec iptables (blocage par exemple), cela n'a pas d'importance. Selon vos contextes, il peut être judicieux d'y mettre une valeur correcte (surveillance sur des logs SSH par exemple).
- La valeur "maxretry" est dans mon cas paramétrée sur 1. La raison est simple, la ligne de log que je souhaite détecter via mon filtre "filtre-perso" n'apparaîtra qu'une fois par événement, ce qui n'est pas le cas d'un brute force SSH par exemple. Si je veux que mon action soit déclenchée, je dois dire à Fail2ban qu'il le fasse dès la première fois qu'il remarque que mon filtre a trouvé une occurrence.
- On voit ensuite bien que dans les champs "filter" et "banaction", j'y indique les filtre et actions personnalisés que je viens de créer. Je ne détaillerais pas ici les tests de bon fonctionnement puisque le cas d'utilisation du cours ne correspondra sûrement pas à votre contexte spécifique. Cependant, quelques choses sont à savoir lorsque l'on souhaite debugger fail2ban.
VI. Commande de diagnostics Fail2ban
Voici quelques commandes et astuces qui vous permettront de diagnostiquer Fail2ban, ce que l'on doit souvent faire lorsque l'on créer notre propre configuration !
- Pensez à utiliser la commande fail2ban-regex pour tester vos expressions régulières comme indiqué dans la partie "Création d'un filtre personnalisé".
- Il est possible d'augmenter le loglevel de fail2ban dans le fichier /etc/fail2ban/fail2ban.log en passant la valeur "LOGLEVEL=" à 4 (3 par défaut).
- Pour voir les jails actives, utilisez la commande suivante :
fail2ban-client status
- Pour voir l'état d'un jail, et notamment les détections faites, utilisez la commande suivante :
fail2ban-client status <nomjail>
Par exemple :
fail2ban-client status dhcp-perso
- Lorsque fail2ban rencontre un problème au démarrage, il est possible d'avoir des logs un peu plus bavards via le redémarrage du côté client, ce qui met généralement sur la bonne voie :
fail2ban-client reload
C'est la fin de ce cours sur les filtres et actions personnalisés dans Fail2ban, n'hésitez pas à partager vos avis en commentaire ou à poser vos questions dans notre forum ! Le prochain cours sur Fail2ban portera sur l'intégration d'un plugin WordPress Fail2ban pour protéger son CMS.
Bonjour,
Avez-vous des conseils sur les actions à effectuées lorsqu’une IP est bannie. Je reçois un mail du serveur, on a une portion de log, ce n’est pas toujours évident de déterminer ce que c’est. Bien souvent, c’est un bot qui scan et cherche des URL bizarre pouvant amener éventuellement à faille de sécurité. Mais est-ce qu’il faut mener des actions particulières? J’ai un gros doute sur l’utilité d’envoyer un mail « abuse report ». Votre avis sur le sujet ou un article à ce propos m’intéresse.
Merci.