Fail2ban : protéger SSH contre le brute force
Fail2ban lit les journaux des services, repère les tentatives de connexion répétées échouées et bloque temporairement l'adresse IP de l'attaquant via le pare-feu. Pour protéger SSH, il suffit d'installer le paquet, de créer /etc/fail2ban/jail.local avec une section [sshd] (enabled = true, maxretry, findtime, bantime) et de redémarrer le service ; l'état se vérifie avec fail2ban-client status sshd.
Fail2ban est un démon qui surveille les journaux des services, repère les tentatives de connexion répétées et bloque temporairement l'adresse IP d'où elles proviennent. Pour SSH, c'est la protection la plus simple contre le test de mots de passe : les robots cessent de s'acharner après quelques échecs. Vous trouverez ci-dessous la configuration de fail2ban, de l'installation jusqu'à la vérification des bans et les erreurs typiques.
Pourquoi utiliser fail2ban si l'on a des clés SSH
Tout serveur dont le port 22 est ouvert reçoit des tentatives de connexion de robots quelques minutes seulement après sa mise en service. Vous pouvez le constater vous-même :
$ sudo journalctl -u ssh --since "1 hour ago" | grep -c "Failed password"
412
Si la connexion par mot de passe est désactivée et que seules les clés sont acceptées, il est pratiquement impossible de forcer l'accès. Fail2ban reste néanmoins utile : il réduit le bruit dans les journaux, allège la charge due aux milliers de connexions et protège contre une erreur de configuration qui laisserait le mot de passe actif. C'est une seconde couche de défense, et non un remplacement des clés.
Fonctionnement de fail2ban
La logique repose sur trois éléments :
- Filtre (filter) — un ensemble d'expressions régulières qui repèrent, dans le journal, les lignes correspondant à un échec de connexion et en extraient l'IP. Les filtres se trouvent dans
/etc/fail2ban/filter.d/. - Action (action) — la mesure à prendre contre le contrevenant : ajouter une règle dans iptables, nftables, ufw ou firewalld. Les actions se trouvent dans
/etc/fail2ban/action.d/. - Prison (jail) — l'association d'un filtre, d'une action, d'une source de journaux et de seuils. Par exemple, la jail
sshdsurveille le journal de SSH.
Si, pendant la durée findtime, une même IP accumule maxretry correspondances, l'adresse est bloquée pendant bantime. Une fois ce délai écoulé, le ban est levé automatiquement.
Installation de fail2ban
Sur Debian et Ubuntu :
sudo apt update
sudo apt install fail2ban
Sur RHEL, Rocky, AlmaLinux, le paquet se trouve dans le dépôt EPEL :
sudo dnf install epel-release
sudo dnf install fail2ban
Activez le démarrage automatique et vérifiez l'état du service :
sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban
Sous Debian et Ubuntu, la jail SSH est déjà activée par défaut via /etc/fail2ban/jail.d/defaults-debian.conf. Dans la famille RHEL, rien n'est activé après l'installation : il faut activer les jails manuellement.
Où se trouvent les réglages : jail.conf et jail.local
Le fichier principal est /etc/fail2ban/jail.conf, mais on ne le modifie pas : il serait écrasé à la mise à jour du paquet. Vos réglages vont dans /etc/fail2ban/jail.local ou dans des fichiers séparés /etc/fail2ban/jail.d/*.local. Fail2ban lit les fichiers dans cet ordre, chacun remplaçant le précédent :
jail.confjail.d/*.confjail.localjail.d/*.local
Ne recopiez pas tout jail.conf dans jail.local : vous figeriez les anciennes valeurs par défaut. Dans jail.local, n'écrivez que ce que vous changez.
Configurer fail2ban pour SSH : un jail.local minimal
Créez le fichier :
sudo nano /etc/fail2ban/jail.local
Et ajoutez-y :
[DEFAULT]
# Vos adresses, qui ne doivent jamais être bannies
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
bantime = 1h
findtime = 10m
maxretry = 5
# D'où lire les journaux : journal systemd ou fichiers
backend = systemd
[sshd]
enabled = true
port = ssh
maxretry = 3
Redémarrez le service et vérifiez que la jail est active :
$ sudo systemctl restart fail2ban
$ sudo fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: sshd
Signification des paramètres
| Paramètre | Signification | Exemple |
|---|---|---|
enabled | la jail est-elle active | true |
port | port(s) à bloquer pour le contrevenant | ssh, 2222, ssh,2222 |
maxretry | nombre d'erreurs tolérées avant le ban | 3 |
findtime | fenêtre dans laquelle les erreurs sont comptées | 10m |
bantime | durée du ban ; -1 — définitif | 1h, 1d |
ignoreip | adresses et sous-réseaux jamais bannis | 10.0.0.0/8 |
backend | source des journaux | systemd, auto |
logpath | chemin du fichier journal avec un backend fichier | /var/log/auth.log |
banaction | pare-feu utilisé pour le ban | nftables-multiport, ufw |
Les durées peuvent s'écrire avec un suffixe : s, m, h, d, w. Un nombre sans suffixe est exprimé en secondes.
backend : systemd ou fichier
Sur Debian 12 et Ubuntu 24.04 récents, le fichier /var/log/auth.log peut être absent si rsyslog n'est pas installé : les journaux de SSH ne se trouvent alors que dans le journal systemd. Il faut dans ce cas backend = systemd, sinon fail2ban ne démarre pas et signale l'absence du fichier journal. Si rsyslog est présent, la variante fichier convient :
[sshd]
enabled = true
backend = auto
logpath = /var/log/auth.log
Sur les systèmes RHEL, le fichier équivalent est /var/log/secure.
SSH sur un port non standard
Si sshd écoute par exemple sur le port 2222, indiquez-le dans la jail : sinon fail2ban bloquera le port 22, et l'attaque continuera sur le 2222 :
[sshd]
enabled = true
port = 2222
Pour bloquer simultanément tous les ports pour le contrevenant, utilisez l'action iptables-allports ou nftables-allports via le paramètre banaction.
Choisir le pare-feu : iptables, nftables, ufw, firewalld
Par défaut, Debian utilise banaction = nftables (iptables dans les anciennes versions), et RHEL utilise firewalld. Si le serveur est configuré avec ufw, il est plus pratique que les bans apparaissent dans ufw :
[DEFAULT]
banaction = ufw
Pour firewalld :
[DEFAULT]
banaction = firewallcmd-rich-rules
Pour vérifier que les règles ont bien été créées, lancez sudo nft list ruleset | grep f2b ou sudo iptables -L -n | grep f2b : fail2ban crée des chaînes préfixées par f2b-.
Vérifier le fonctionnement : fail2ban-client status
L'outil de gestion principal est fail2ban-client. État d'une jail donnée :
$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 2
| |- Total failed: 147
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 4
|- Total banned: 38
`- Banned IP list: 45.148.10.12 92.118.39.7 185.224.128.40 218.92.0.112
On y voit combien d'erreurs sont comptées actuellement dans la fenêtre, combien d'IP sont bloquées et lesquelles. Pour tester la protection en conditions réelles, essayez de vous connecter plusieurs fois avec un mauvais mot de passe depuis une autre machine (qui ne figure pas dans ignoreip) : après la troisième tentative, la connexion ne doit plus s'établir.
Le journal de fail2ban lui-même se trouve dans /var/log/fail2ban.log :
$ sudo tail -n 3 /var/log/fail2ban.log
2026-10-14 09:12:41,118 fail2ban.filter [812]: INFO [sshd] Found 218.92.0.112
2026-10-14 09:12:44,302 fail2ban.filter [812]: INFO [sshd] Found 218.92.0.112
2026-10-14 09:12:47,551 fail2ban.actions [812]: NOTICE [sshd] Ban 218.92.0.112
Débloquer une IP dans fail2ban
Si vous vous êtes bloqué vous-même, ou si un collègue l'a été, levez le ban depuis la console du serveur (via le panneau de l'hébergeur ou depuis une autre IP) :
sudo fail2ban-client set sshd unbanip 203.0.113.25
Lever tous les bans dans toutes les jails :
sudo fail2ban-client unban --all
Bloquer une adresse manuellement, sans attendre le déclenchement du filtre :
sudo fail2ban-client set sshd banip 198.51.100.7
Pour éviter que le problème ne se reproduise, ajoutez vos adresses statiques ou le sous-réseau du bureau dans ignoreip.
Ban progressif pour les récidivistes
Beaucoup de robots reviennent dès que le ban est levé. Depuis la version 0.11, fail2ban permet d'allonger la durée du ban pour les récidivistes :
[DEFAULT]
bantime = 1h
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 4w
Chaque nouveau ban de la même IP sera plus long que le précédent, sans dépasser quatre semaines. Autre solution pour les anciennes versions : la jail recidive, qui lit le journal de fail2ban lui-même et bloque longtemps les adresses apparues plusieurs fois :
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
bantime = 1w
findtime = 1d
maxretry = 5
Tester un filtre : fail2ban-regex
Si la jail fonctionne mais ne bannit personne, vérifiez que le filtre repère bien des lignes dans le journal. Pour un journal fichier :
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
Pour le journal systemd :
sudo fail2ban-regex systemd-journal sshd
Dans la sortie, regardez la ligne Lines: ... matched. Zéro correspondance signifie que le filtre ne correspond pas au format des journaux, ou que la mauvaise source a été indiquée. Avant tout redémarrage, il est utile de vérifier la syntaxe de l'ensemble de la configuration :
sudo fail2ban-client -t
Erreurs fréquentes
- Le service ne démarre pas : « Have not found any log file for sshd jail ». Le fichier
/var/log/auth.logn'existe pas. Indiquezbackend = systemdou installez rsyslog. - Les bans apparaissent dans le statut, mais l'attaque continue. Le mauvais port est indiqué (SSH a été déplacé), ou une règle d'autorisation antérieure du pare-feu prend le dessus. Vérifiez
portet la sortie denft list ruleset. - Les modifications n'ont pas d'effet. Vous avez modifié
jail.conf, alors qu'une autre valeur est définie dansjail.localoujail.d/*.local. Consultez la valeur effective :sudo fail2ban-client get sshd maxretry. - Vous vous êtes bloqué vous-même. Débloquez-vous depuis la console et ajoutez votre IP dans
ignoreip. - Fail2ban ne voit pas les attaques dans Docker. Les ports des conteneurs sont publiés via la chaîne DOCKER, qui contourne INPUT. Pour ces services, utilisez
chain = DOCKER-USERdans l'action.
Autres mesures pour protéger SSH
Fail2ban fonctionne bien en complément des réglages de base dans /etc/ssh/sshd_config :
PasswordAuthentication no
PermitRootLogin no
MaxAuthTries 3
Après modification, vérifiez la configuration avec sudo sshd -t, puis redémarrez le service. Ne fermez pas la session actuelle tant que vous n'avez pas confirmé qu'une nouvelle connexion par clé fonctionne. Vous pouvez aussi restreindre l'accès SSH aux seules adresses nécessaires au niveau du pare-feu.
Conclusion
Configurer fail2ban se résume à quelques étapes : installer le paquet, créer un jail.local avec une section [sshd], choisir le bon backend et le bon port, définir maxretry, findtime et bantime, ajouter vos adresses dans ignoreip, puis vérifier avec fail2ban-client status sshd. Associée à une connexion par clés uniquement, cette configuration protège efficacement SSH contre le test de mots de passe. La protection d'un serveur et l'usage de fail2ban sont détaillés en pratique dans le cours Linux.
Questions fréquentes
Faut-il fail2ban si la connexion par mot de passe est désactivée ?
Ce n'est pas obligatoire, mais c'est utile : il retire des milliers de tentatives parasites des journaux, allège la charge, et protège au cas où quelqu'un réactiverait le mot de passe.
Comment voir toutes les IP bloquées dans toutes les jails ?
Exécutez sudo fail2ban-client banned : la commande affiche la liste des adresses bloquées par jail. Pour une seule jail, utilisez fail2ban-client status sshd.
Les bans survivent-ils au redémarrage du serveur ?
Oui. fail2ban enregistre les bans dans sa base SQLite (/var/lib/fail2ban/fail2ban.sqlite3) et restaure les blocages en cours au démarrage, sauf si le paramètre dbpurgeage les a supprimés plus tôt.
Fail2ban peut-il protéger autre chose que SSH ?
Oui, il livre des filtres pour nginx, Apache, Postfix, Dovecot et d'autres services. Il suffit d'activer la jail correspondante dans jail.local, par exemple [nginx-http-auth] avec enabled = true.
En quoi fail2ban diffère-t-il d'une restriction dans le pare-feu ?
Le pare-feu autorise ou interdit statiquement des adresses, tandis que fail2ban bannit dynamiquement ceux qui se font remarquer dans les journaux. On combine souvent les deux : une liste blanche dans le pare-feu, et fail2ban pour le reste.
Ce sujet est traité en détail avec de la pratique dans le cours « Linux: с нуля до уверенного администрирования ».
Voir le cours