Ce qu'il fait
fail2ban lit les journaux. Quand une adresse échoue à se connecter maxretry fois pendant findtime, il ajoute une règle de pare-feu qui bloque cette adresse pendant bantime. C'est tout. Il n'inspecte pas le trafic SSH et ne rend pas un mot de passe faible solide.
Installer
sudo apt install fail2ban python3-systemd
python3-systemd lui permet de lire le journal systemd. Sur la famille Red Hat, le paquet est dans EPEL. Sur Debian 13 et Ubuntu 24.04, le paquet active déjà la jail sshd, avec le backend systemd et nftables, via /etc/fail2ban/jail.d/defaults-debian.conf.
Configurer : jail.local
Ne modifiez pas jail.conf, car les mises à jour peuvent le remplacer. Placez vos réglages dans /etc/fail2ban/jail.local :
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
bantime = 1h
findtime = 10m
maxretry = 5
[sshd]
enabled = true
backend = systemd
| Réglage | Signification | Valeur par défaut du paquet |
|---|---|---|
bantime | Durée d'un bannissement | 10m |
findtime | La fenêtre pendant laquelle les échecs s'additionnent | 10m |
maxretry | Échecs autorisés dans cette fenêtre | 5 |
ignoreip | Adresses jamais bannies | aucune |
backend | D'où viennent les journaux | auto |
Ajoutez votre propre adresse fixe à ignoreip, pour que quelques fautes de frappe ne puissent pas vous enfermer dehors. Si votre adresse change, assurez-vous d'avoir une console de secours.
Utilisez backend = systemd quand les journaux SSH vont dans le journal systemd, comme sur Debian récent, qui peut ne pas avoir de /var/log/auth.log du tout. Sur un système qui écrit ce fichier, vous pouvez utiliser backend = auto et logpath à la place.
Si sshd écoute sur un autre port, ajoutez port = 2222 à la jail. La règle que nous avons vue ne correspondait qu'au port du réglage de la jail (tcp dport 22) : un bannissement sur le mauvais port ne bloque rien.
Testez le fichier, puis redémarrez :
sudo fail2ban-client -t
sudo systemctl restart fail2ban
Vérifier que cela fonctionne vraiment
sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 4
| `- Journal matches: _SYSTEMD_UNIT=ssh.service + _COMM=sshd
`- Actions
|- Currently banned: 1
|- Total banned: 1
`- Banned IP list: 203.0.113.20
Faites un vrai test. Depuis une autre adresse, ni le serveur lui-même ni une adresse de ignoreip, faites échouer une connexion par mot de passe et relancez la commande. Total failed doit augmenter. S'il reste à 0, la jail ne lit pas les bons journaux et le reste ne sert à rien. Comparez la correspondance du journal avec le nom de votre unité, ssh.service ou sshd.service, et vérifiez avec journalctl -u ssh -n 20.
Une fois banni, le client voit ceci :
ssh: connect to host 203.0.113.10 port 22: Connection refused
On peut voir la règle de pare-feu avec sudo nft list ruleset :
table inet f2b-table {
set addr-set-sshd {
type ipv4_addr
elements = { 203.0.113.20 }
}
chain f2b-chain {
type filter hook input priority filter - 1; policy accept;
tcp dport 22 ip saddr @addr-set-sshd reject with icmp port-unreachable
}
}
Commandes de tous les jours
| Objectif | Commande |
|---|---|
| Lister les jails | sudo fail2ban-client status |
| Débannir une adresse | sudo fail2ban-client set sshd unbanip 203.0.113.20 |
| Tout débannir | sudo fail2ban-client unban --all |
| Bannir à la main | sudo fail2ban-client set sshd banip 203.0.113.20 |
| Voir les bannissements et leur fin | sudo fail2ban-client get sshd banip --with-time |
| Ignorer une adresse tout de suite | sudo fail2ban-client set sshd addignoreip 203.0.113.10 |
| Lire les réglages utilisés | sudo fail2ban-client get sshd bantime |
| Lire son journal | sudo tail /var/log/fail2ban.log |
Le changement fait avec addignoreip ne dure que jusqu'au prochain rechargement. Ajoutez-le à jail.local pour le conserver.
Ce qui compte comme un échec
Nous avons testé le mode par défaut sur OpenSSH 10.0 avec ces résultats :
- Un mauvais mot de passe comptait, tout comme un mauvais mot de passe pour un utilisateur qui n'existe pas.
- Une déconnexion Too many authentication failures comptait pour un seul échec.
- Les connexions qui proposaient une mauvaise clé puis abandonnaient ne comptaient pas. Elles apparaissent dans le journal sous la forme
Connection closed by authenticating user.
Avec mode = aggressive dans la jail [sshd], les connexions avec une mauvaise clé étaient comptées aussi. Il attrape plus de monde, mais il facilite aussi le bannissement de quelqu'un dont le client est mal configuré : gardez donc ignoreip à jour.
Ce contre quoi il ne protège pas
- Une clé volée ou un mot de passe divulgué. Une connexion correcte n'est pas un échec : il n'y a donc pas de bannissement.
- Des tentatives lentes ou distribuées. Beaucoup d'adresses faisant une ou deux tentatives chacune restent sous la limite.
- Une faille dans sshd lui-même. Il réagit à des lignes de journal, après coup.
- Les autres services, à moins qu'ils aient leurs propres jails.
Il peut aussi se retourner contre vous : tous ceux qui sont derrière le NAT d'un bureau partagent une seule adresse, et les erreurs d'une personne peuvent donc enfermer dehors tout le bureau.
Si une clé fuit, il faut savoir où elle est installée et retirer la clé SSH de chaque serveur.
Ce qui compte davantage
Si le serveur n'accepte que des clés, les tentatives de devinette de mot de passe n'ont rien à deviner, quel que soit leur nombre. Faites donc ceci en premier :
- Utilisez une clé et désactivez la connexion par mot de passe.
- Limitez qui peut atteindre le port 22 avec un pare-feu ou un VPN, si vous le pouvez.
- Passez en revue le reste de vos réglages sshd.
Après cela, fail2ban est un complément utile qui rend les journaux plus calmes. Par ailleurs, OpenSSH 9.8 et les versions suivantes ont leur propre PerSourcePenalties, activé par défaut, qui refuse brièvement les adresses au comportement abusif. C'est bien plus court qu'un bannissement fail2ban typique : les deux fonctionnent donc bien côte à côte.
Questions
Comment débannir une IP dans fail2ban ?
Lancez sudo fail2ban-client set sshd unbanip suivi de l'adresse. sudo fail2ban-client unban --all lève tous les bannissements, dans toutes les jails.
Comment vérifier que fail2ban fonctionne ?
Lancez sudo fail2ban-client status sshd, ratez une connexion depuis une autre adresse, puis relancez la commande. Total failed doit augmenter. S'il reste à 0, la jail ne lit pas les journaux SSH.
Pourquoi un client banni voit-il Connection refused ?
Avec l'action nftables par défaut sur Debian, une adresse bannie reçoit un rejet : ssh affiche donc Connection refused plutôt qu'un délai dépassé. Une action qui abandonne les paquets ressemblerait à un délai dépassé.
Les mauvaises clés SSH comptent-elles comme des échecs ?
Pas dans le mode par défaut. Dans notre test, cinq connexions avec une mauvaise clé n'ont rien ajouté au compteur. mode = aggressive dans la jail les a comptées.
Sources
- jail.conf(5), fail2ban
- Filtre sshd, fail2ban
- Documentation de Fail2Ban
- sshd_config(5), PerSourcePenalties