Fail2ban lit vos journaux, repère les échecs d'authentification répétés et bannit l'adresse IP fautive dans le pare-feu. Un serveur SSH exposé sur Internet encaisse des milliers de tentatives automatisées par jour ; Fail2ban les coupe après trois essais, sans que vous ayez à surveiller quoi que ce soit.
Ce guide installe Fail2ban, crée une prison SSH, prouve le bannissement par une vraie attaque, puis traite le piège qui fait perdre le plus de temps : une prison qui tourne, qui semble configurée, et qui ne bannit jamais personne.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre le trio prison, filtre et action qui structure Fail2ban
- Configurer une prison SSH dans
jail.local, sans jamais toucher àjail.conf - Vérifier qu'un bannissement bloque réellement la connexion, et pas seulement dans l'affichage
- Diagnostiquer une prison qui ne bannit rien, avec
fail2ban-regex - Piéger les récidivistes avec la prison
recidive - Choisir entre Fail2ban, CrowdSec et un pare-feu applicatif
Prérequis
Section intitulée « Prérequis »- Un serveur Linux avec un accès
rootousudo. Le lab de référence est une Debian 12. - Un service qui journalise ses échecs d'authentification, typiquement SSH.
- Des notions de pare-feu : Fail2ban ne bloque rien lui-même, il pilote
iptables,nftablesou UFW.
Le trio prison, filtre et action
Section intitulée « Le trio prison, filtre et action »Tout Fail2ban tient dans trois notions. Les confondre est la première source d'erreur.
Un filtre est une collection d'expressions régulières qui décrivent à quoi ressemble un échec dans un fichier de log. Fail2ban en livre 94 par défaut : SSH, Nginx, Apache, Postfix, Dovecot et bien d'autres.
Une action est ce qui se passe quand le seuil est franchi. Par défaut, ajouter une règle de rejet dans le pare-feu, mais cela peut aussi être un courriel ou un appel d'API.
Une prison (jail) assemble les deux : sur ce fichier de log, avec ce filtre, si tu vois N échecs en T secondes, applique cette action pendant D secondes.
| Réglage | Rôle | Valeur courante |
|---|---|---|
maxretry | échecs tolérés avant sanction | 3 à 5 |
findtime | fenêtre d'observation | 10 minutes |
bantime | durée du bannissement | 10 minutes à plusieurs heures |
ignoreip | adresses jamais bannies | votre IP fixe, le réseau local |
Étape 1 - Installer Fail2ban
Section intitulée « Étape 1 - Installer Fail2ban »sudo apt update && sudo apt install -y fail2bansudo dnf install -y epel-releasesudo dnf install -y fail2banVérifiez la version installée, elle a son importance :
fail2ban-server --versionFail2Ban v1.0.2Étape 2 - Configurer une prison SSH
Section intitulée « Étape 2 - Configurer une prison SSH »Ne modifiez jamais /etc/fail2ban/jail.conf. Ce fichier appartient au paquet, et la prochaine mise à jour écrasera vos changements sans prévenir. Fail2ban lit en plus un fichier jail.local, dont les valeurs priment sur celles de jail.conf. C'est là, et nulle part ailleurs, que vous écrivez.
[DEFAULT]# Durée du bannissementbantime = 10m# Fenêtre d'observationfindtime = 10m# Nombre d'échecs toléré dans la fenêtremaxretry = 3# Ne jamais bannir ces adressesignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
[sshd]enabled = trueport = sshlogpath = /var/log/auth.logLa section [DEFAULT] s'applique à toutes les prisons ; chaque section nommée peut la surcharger. Ici, une seule prison est active, [sshd], qui réutilise le filtre sshd livré avec Fail2ban.
Rechargez, puis vérifiez que la prison est bien montée :
sudo systemctl restart fail2bansudo fail2ban-client status sshdStatus for the jail: sshd|- Filter| |- Currently failed: 0| |- Total failed: 0| `- File list: /var/log/auth.log`- Actions |- Currently banned: 0 |- Total banned: 0 `- Banned IP list:Étape 3 - Prouver que ça bannit
Section intitulée « Étape 3 - Prouver que ça bannit »Une prison qui affiche Running ne prouve rien. La seule vérification qui vaille est de se faire bannir soi-même, depuis une autre machine, en gardant une session ouverte pour se rattraper.
Depuis une machine de test, enchaînez quatre connexions avec un mauvais mot de passe :
for i in 1 2 3 4; do sshpass -p mauvais ssh -o PreferredAuthentications=password \ -o PubkeyAuthentication=no victime@192.168.1.50 exitdonePuis, sur le serveur :
sudo fail2ban-client status sshd|- Filter| |- Currently failed: 0| |- Total failed: 3`- Actions |- Currently banned: 1 |- Total banned: 1 `- Banned IP list: 172.17.0.5Trois échecs comptés, une adresse bannie. Notez que le quatrième essai n'apparaît pas : l'adresse était déjà bloquée avant qu'il n'arrive.
Le journal raconte la même histoire, en clair :
sudo grep -E "Found|Ban" /var/log/fail2ban.log | tail -4[sshd] Found 172.17.0.5 - 2026-07-12 20:03:22[sshd] Found 172.17.0.5 - 2026-07-12 20:03:27[sshd] Found 172.17.0.5 - 2026-07-12 20:03:31[sshd] Ban 172.17.0.5Le bannissement est-il réel ?
Section intitulée « Le bannissement est-il réel ? »C'est la question que personne ne pose, et c'est pourtant la seule qui compte. Fail2ban peut afficher une adresse bannie sans qu'aucune règle n'ait été posée, par exemple si le pare-feu n'est pas celui qu'il croit.
Regardez la chaîne créée dans le pare-feu :
sudo iptables -L f2b-sshd -nChain f2b-sshd (1 references)target prot opt source destinationREJECT 0 -- 172.17.0.5 0.0.0.0/0 reject-with icmp-port-unreachableRETURN 0 -- 0.0.0.0/0 0.0.0.0/0Et vérifiez le comportement depuis la machine bannie :
ssh: connect to host 192.168.1.50 port 22: Connection refusedDétection, règle de pare-feu, connexion refusée. La chaîne est complète.
Débannir
Section intitulée « Débannir »sudo fail2ban-client set sshd unbanip 172.17.0.5La règle disparaît immédiatement du pare-feu et la connexion redevient possible. Sans cette commande, il faut attendre l'expiration du bantime.
Étape 4 - Le piège : une prison qui ne bannit jamais rien
Section intitulée « Étape 4 - Le piège : une prison qui ne bannit jamais rien »C'est l'échec le plus fréquent, et le plus déroutant. Le service tourne, la prison est active, l'attaque est bien en cours, et le compteur reste obstinément à zéro.
Fail2ban fournit l'outil de diagnostic qui donne la réponse en une commande. Il rejoue le filtre sur le fichier de log et dit exactement ce qu'il a compris :
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.confVoici la sortie obtenue en lab, sur un serveur pourtant réellement attaqué :
Failregex: 4 total| 14) [4] ^<F-NOFAIL>pam_[a-z]+\(sshd:auth\):\s+authentication failure;</F-NOFAIL>...
Lines: 4 lines, 4 ignored, 0 matched, 0 missedQuatre lignes lues, quatre ignorées, aucune retenue. La clé est la balise <F-NOFAIL> : Fail2ban reconnaît la ligne pam_unix ... authentication failure, mais la classe délibérément comme « pas un échec ». Il attend la ligne suivante, celle que sshd écrit lui-même : Failed password for ... from ....
Dans notre lab, cette ligne n'arrivait jamais dans auth.log, parce que sshd avait été lancé avec l'option -e, qui envoie ses journaux sur la sortie d'erreur au lieu de syslog. PAM écrivait bien dans le fichier, mais pas sshd.
La règle à retenir tient en une phrase : si le compteur Total failed reste à zéro pendant une attaque, le problème est dans le log, pas dans la prison.
Étape 5 - Punir les récidivistes
Section intitulée « Étape 5 - Punir les récidivistes »Un attaquant patient revient après l'expiration du bannissement. La prison recidive existe précisément pour lui : elle surveille le journal de Fail2ban lui-même, et bannit longuement ceux qui se font bannir de façon répétée.
[recidive]enabled = truelogpath = /var/log/fail2ban.logbanaction = %(banaction_allports)sbantime = 1wfindtime = 1dmaxretry = 3Deux détails la rendent redoutable. Elle lit le journal de Fail2ban, donc toute prison alimente son compteur. Et banaction_allports bloque l'adresse sur tous les ports, pas seulement celui du service attaqué : celui qui insiste sur SSH perd aussi l'accès au serveur web.
Sécurité : ce que Fail2ban ne fait pas
Section intitulée « Sécurité : ce que Fail2ban ne fait pas »Fail2ban est réactif, jamais préventif. Il agit après coup, sur des échecs déjà survenus. Il ne remplace donc ni l'authentification par clé, ni le durcissement de SSH, ni un pare-feu bien réglé. Un serveur dont SSH n'accepte que les clés n'a aucune tentative de mot de passe à bannir, ce qui est infiniment plus solide.
Il ne voit que ce qui est journalisé. Une attaque qui ne produit pas de ligne de log lui est invisible, par construction.
Il protège mal contre le distribué. Trois essais par adresse, sur dix mille adresses, ne déclenchent jamais rien. C'est la limite fondamentale du modèle, et c'est ce qui a donné naissance aux approches collaboratives.
Fail2ban, CrowdSec ou un pare-feu applicatif ?
Section intitulée « Fail2ban, CrowdSec ou un pare-feu applicatif ? »La question est légitime, et la réponse n'est pas « le plus récent gagne ».
Fail2ban est présent dans tous les dépôts, se configure en un fichier, et ne dépend d'aucun service tiers. Sa force est sa simplicité et son universalité : il sait lire n'importe quel log dès qu'on lui écrit une expression régulière. C'est le bon choix sur un serveur isolé, un homelab, une machine qui n'a pas vocation à parler au monde.
CrowdSec ajoute ce qui manque à Fail2ban : une liste noire communautaire. Une adresse qui attaque quelqu'un d'autre est bloquée chez vous avant même de vous avoir touché. C'est la réponse au problème des attaques distribuées, au prix d'une architecture plus lourde et d'une dépendance à un service en ligne.
SysWarden va plus loin encore, avec un pare-feu applicatif, des listes de blocage et du géoblocage.
Le projet Fail2ban lui-même mérite un mot d'honnêteté : sa dernière version publiée date d'avril 2024, ce qui a fait dire à beaucoup qu'il était abandonné. Le dépôt raconte autre chose : des commits réguliers jusqu'en juin 2026, plus de 18 000 étoiles, et un développement actif. Le projet ne publie pas souvent, il ne meurt pas pour autant.
Dépannage
Section intitulée « Dépannage »Avant le tableau, un réflexe : les trois quarts des problèmes de Fail2ban se diagnostiquent avec fail2ban-regex, qui rejoue le filtre sur le log et montre ce qui a été compris.
| Symptôme | Cause | Correctif |
|---|---|---|
Total failed: 0 pendant une attaque | le service ne journalise pas dans logpath | vérifier le fichier, ou passer en backend = systemd |
0 matched, N ignored | la ligne est marquée NOFAIL | c'est une ligne PAM, il manque la ligne du service |
0 matched, N missed | le filtre ne reconnaît pas le format | vérifier le format de date et la version du filtre |
| IP bannie mais connexion possible | aucune règle posée dans le pare-feu | iptables -L f2b-<prison> -n |
| Vous êtes banni de votre serveur | ignoreip incomplet | accès console, fail2ban-client set <prison> unbanip <ip> |
| Les bannissements disparaissent au redémarrage | pas de persistance | activer la base : dbfile dans fail2ban.local |
| Rien ne démarre | erreur de syntaxe dans jail.local | fail2ban-client -t teste la configuration |
À retenir
Section intitulée « À retenir »- Fail2ban assemble un filtre (à quoi ressemble un échec), une prison (le seuil) et une action (le pare-feu).
- Ne touchez jamais à
jail.conf: la mise à jour du paquet l'écrase. Tout se passe dansjail.local. - Renseignez
ignoreipen premier, sinon vous vous bannirez vous-même. - Une prison active ne prouve rien. Vérifiez le bannissement en vous faisant bannir, et contrôlez la règle de pare-feu.
- Si le compteur reste à zéro pendant une attaque, le problème est dans le log, pas dans la prison.
fail2ban-regexle dit en une commande. - La balise
<F-NOFAIL>explique les lignes vues mais ignorées : Fail2ban attend la ligne du service, pas celle de PAM. - La prison
recidivebannit une semaine, sur tous les ports, ceux qui reviennent. - Fail2ban est réactif : il ne remplace ni les clés SSH, ni le durcissement. Il est aussi impuissant face aux attaques distribuées, ce à quoi CrowdSec répond.
- Le projet ne publie plus depuis avril 2024 mais reste développé : commits réguliers en 2026.