Comment configurer fail2ban pour SSH

Installez fail2ban, créez /etc/fail2ban/jail.local avec une jail [sshd] activée et backend = systemd, redémarrez-le et vérifiez avec fail2ban-client status sshd. Il bannit les adresses après des échecs de connexion répétés. Il réduit le bruit et ralentit les tentatives de devinette, mais désactiver la connexion par mot de passe vous protège bien davantage.

Mis à jour le . Exécuté avec fail2ban 1.1.0 sur un conteneur Debian 13 jetable démarré avec systemd et utilisant nftables, avec OpenSSH 10.0, et de vrais échecs de connexion depuis un second conteneur. Le fichier de la jail par défaut a aussi été lu sur Ubuntu 24.04.

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églageSignificationValeur par défaut du paquet
bantimeDurée d'un bannissement10m
findtimeLa fenêtre pendant laquelle les échecs s'additionnent10m
maxretryÉchecs autorisés dans cette fenêtre5
ignoreipAdresses jamais banniesaucune
backendD'où viennent les journauxauto

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

ObjectifCommande
Lister les jailssudo fail2ban-client status
Débannir une adressesudo fail2ban-client set sshd unbanip 203.0.113.20
Tout débannirsudo fail2ban-client unban --all
Bannir à la mainsudo fail2ban-client set sshd banip 203.0.113.20
Voir les bannissements et leur finsudo fail2ban-client get sshd banip --with-time
Ignorer une adresse tout de suitesudo fail2ban-client set sshd addignoreip 203.0.113.10
Lire les réglages utiliséssudo fail2ban-client get sshd bantime
Lire son journalsudo 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 :

  1. Utilisez une clé et désactivez la connexion par mot de passe.
  2. Limitez qui peut atteindre le port 22 avec un pare-feu ou un VPN, si vous le pouvez.
  3. 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

Autres guides : Sécuriser un serveur

Tous les guides