====== 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//.