====== Bloquer les attaques en force brute avec fail2ban ======
En cours de rédaction
Sources :
* [[https://www.it-connect.fr/filtres-et-actions-personnalises-dans-fail2ban/|Filtres et actions personnalisés dans Fail2ban]] (fr) (it-connect.fr)
* [[https://www.the-art-of-web.com/system/fail2ban-filters/|Optimising your Fail2Ban filters]] (en) (the-art-of-web.com)
===== Terminologie =====
* filtre (filter) : type d'événement à surveiller
* action (action) : action de blocage, de protection ou de notification
* prison (jail) : conditions d'engagement d'une //action// sur la base des événements définis par un //filtre//
===== Ajouter un filtre personnalisé =====
On peut créer un filtre personnalisé entièrement nouveau ou dérivé d'un filtre existant. On ne //modifie// jamais un filtre installé automatiquement par le paquetage.
Un filtre personnalisé doit impérativement être enregistré dans un fichier "//.local//" **et** ajouté au répertoire "///etc/fail2ban/filter.d//". L'ajout d'un filtre est sans conséquence tant qu'une //prison// ne l'exploite pas.
==== Filtre dérivé ====
Il existe au moins deux techniques de dérivation.
La plus simple mais pas forcément la meilleure consiste à créer un filtre dans lequel on va copier/coller un filtre existant puis effectuer les modifications voulues.
La seconde consiste à créer un filtre qui hérite dynamiquement ((En utilisant un mécanisme d'inclusion.)) d'un filtre pré-existant. On surcharge des éléments définis dans le filtre existant et/ou on complète le mécanisme de détection. L'intérêt de cette méthode est qu'elle permet de bénéficier des mises à jour des filtres existants sur lesquels s'appuie le nouveau filtre. La difficulté tient à la robustesse((Résistance aux mises à jour du filtre existant.)) du type de « surcharge » réalisée.
===== Tester un filtre =====
Avant d'utiliser un filtre dans une prison, il faut impérativement tester ce filtre pour s'assurer qu'il détecte correctement les événements souhaités et eux seuls !
Pour ce faire, on utilise la commande [[https://manpages.debian.org/trixie/fail2ban/fail2ban-regex.1.en.html|fail2ban-regex]] dont la forme générale est la suivante :
fail2ban-regex [OPTIONS] LOG REGEX [IGNOREREGEX]
Si le filtre contient une définition, même vide, de la variable "//ignoreregex//" (très fréquent), il faut impérativement indiquer le fichier de filtre en tant que //IGNOREREGEX//; sinon la commande ne fonctionne pas !
Par exemple, si les logs concernés sont fournis par //journald//:
fail2ban-regex systemd-journal /etc/fail2ban/filter.d/filtre.local /etc/fail2ban/filter.d/filtre.local
Pour que cela fonctionne, le filtre doit contenir une déclaration du service (//unit//) de //journald// concerné, par exemple "journalmatch = _SYSTEMD_UNIT=dovecot.service".
(**à tester : ** fonctionnement - priorité/surcharge)On peut également indiquer le service de journald dans la commande, comme dans l'exemple suivant :
fail2ban-regex --journalmatch='CONTAINER_TAG=nginx' systemd-journal nginx-botsearch
Si les logs sont dans un fichier :
fail2ban-regex /var/log/fichier.log /etc/fail2ban/filter.d/filtre.local /etc/fail2ban/filter.d/filtre.local
systemd-journal
==== Affichage des résultats ====
Par défaut, //fail2ban-regex// n'affiche que des résultats partiels. On dispose des //options// suivantes pour forcer l'affichage :
* %%--%%print-no-ignored
* %%--%%print-no-missed
* %%--%%print-all-matched
* %%--%%print-all-ignored
* %%--%%print-all-missed
Par exemple :
fail2ban-regex --print-all-matched systemd-journal filtre.local filtre.local
===== Activer une prison =====
Les prisons prédéfinies figurent dans le fichier //jail.conf//. Elles ne sont pas activées.
Leur activation se fait de manière sélective en les déclarant dans le fichier //jail.local// et en y établissant la valeur du paramètre //enabled// de la prison à //true// (enabled = true).
===== Ajouter une prison =====
Les //prisons// personnalisées doivent être ajoutées dans le fichier "/etc/fail2ban/jail.local".
Par défaut, une //prison// exploite le filtre de même nom figurant dans "/etc/fail2ban/filter.d. Si le nom est différent, on précise le paramètre //filter// dans la déclaration de la //prison//. On peut ainsi créer plusieurs prisons exploitant le même filtre de manières différentes.
==== Activer une prison ====
Déclarer une prison dans //jail.local// ne suffit pas à l'activer. Il n'est pas nécessaire de relancer (restart) //fail2ban//. Un simple rechargement (reload) suffit à déclencher la relecture des fichiers de configuration et la prise en compte des modifications qu'on y a faites :
service fail2ban reload
Je recommande de vérifier aussitôt l'état de //fail2ban// :
service fail2ban status
===== Bannissement incrémental =====
Sources :
* [[https://visei.com/2020/05/incremental-banning-with-fail2ban/|Incremental banning with Fail2Ban]] (en)
* [[https://github.com/fail2ban/fail2ban/discussions/2952|Using fail2ban over longer time spans]]
===== Idées de filtres =====
==== apache-badbots ====
Le filtre fourni avec Fail2ban contient une liste prédéfinie de robots malveillants. Pour compléter cette liste sans qu'elle soit écrasée par les mises à jour du filtre d'origine, j'ai créé un filtre dérivé qui me permet de gérer ma propre liste qui vient compléter la liste prédéfinie :
[INCLUDES]
before = apache-badbots.conf
[Definition]
mybotcustom = Bytespider|MJ12bot|SeekportBot|serpstatbot|Barkrowler|YandexBot|AhrefsBot|DotBot|MojeekBot|ZoominfoBot|PetalBot|serpstatbot|BitSightBot|wpbot|WellKnownBot|BLEXBot|AwarioBot|ImagesiftBot|Dataprovider|Amazonbot|GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|SemrushBot|externalhit_uatext|SERankingBacklinksBot
failregex = ^ -.*(GET|POST|HEAD).*HTTP.*(?:%(badbots)s|%(badbotscustom)s|%(mybotcustom)s)
==== apache-ratelimit ====
L'idée est de détecter des robots qui ne se présentent pas comme tels. Dans ce cas, le filtre //apache-badbots// devient inopérant. Cependant, si une même IP fait 200 requêtes en 5 secondes, c'est louche.
Attention à l'action qu'on associera à ce filtre car il détectera aussi les robots légitimes que l'on a explicitement autorisés explicitement autorisés ou pas interdits. Personnellement, je m'en sers pour générer un mail d'alerte, sans bannir l'IP.
Source : [[https://odd.blog/2026/03/26/stopping-web-server-abuse-with-fail2ban/Stopping Web Server Abuse with Fail2Ban]] (en)
===== Idées d'actions =====
==== Ne pas bannir ====
Une des actions envisageable est de signaler un bannissement potentiel sans effectuer le bannissement. C'est tout à fait possible mais le fichier jail.conf ne définit pas le raccourci d'action correspondant.
Un tel raccourci se déduit facilement d'un raccourci existant. Par exemple :
# ban & send an e-mail with whois report to the destemail.
action_mw = %(action_)s
%(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
devient, par simple suppression de l'action de bannissement,
# send an e-mail with whois report to the destemail.
action_noban_mw = %(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
que l'on pourra ajouter dans la section //[DEFAULT]// de //jail.local//.