Fail2ban est un outil indispensable pour protéger un serveur exposé sur Internet contre les tentatives de brute-force (SSH, HTTP, etc.). L’outil surveille les logs, détecte les échecs répétés, puis bannit temporairement l’adresse IP via le pare-feu.
Objectifs de cet article :
- Installer Fail2ban sur Ubuntu/Debian
- Comprendre sa philosophie (filters, jails, actions)
- Activer une protection SSH simple et efficace
- Vérifier le bon fonctionnement, dépanner, puis aller plus loin (recidive, notifications)
Pré-requis :
- Un serveur Debian/Ubuntu avec accès sudo
- Un pare-feu actif (UFW recommandé sur Ubuntu) ou iptables/nftables
Installation et démarrage
Sur Debian/Ubuntu récents :
sudo apt update
sudo apt install fail2ban
Activer au démarrage et lancer :
sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban
Philosophie et fichiers importants
- Filters (filtres) : regex qui détectent les lignes suspectes dans les logs (ex :
/etc/fail2ban/filter.d/sshd.conf). - Actions : que fait Fail2ban quand il bannit ? (ex : ajouter une règle firewall via UFW/iptables/nftables).
- Jails : association filtre + action + paramètres (bantime, findtime, maxretry, etc.).
Ne modifiez jamais les fichiers .conf fournis par le paquet ; créez des .local pour surcharger :
- Fichier global :
/etc/fail2ban/jail.local - Dossiers de configuration utilisateurs :
/etc/fail2ban/jail.d/*.localet*.conf(priorité.local)
Les journaux observés peuvent être des fichiers (ex : /var/log/auth.log) ou le journal systemd (backend systemd).
Configuration de base: protéger SSH
Créer un fichier /etc/fail2ban/jail.local :
[DEFAULT]
# Temps de bannissement (ex : 10 minutes)
bantime = 10m
# Fenêtre d'observation des échecs
findtime = 10m
# Nombre d'échecs avant ban
maxretry = 5
# Adresse(s) à ne jamais bannir (mettez votre IP publique)
ignoreip = 127.0.0.1/8 ::1
# Lecture de logs via systemd (souvent plus fiable sur Ubuntu/Debian)
backend = systemd
# Choisissez l'action selon votre pare-feu (voir plus bas)
# banaction = ufw
# banaction = iptables-multiport
# banaction = nftables-multiport
[sshd]
enabled = true
port = 22
# Le filtre sshd est fourni par défaut
filter = sshd
# Journal : laissez Fail2ban deviner avec backend=systemd
# (Sinon: logpath = /var/log/auth.log)
Note : avec
backend = systemd, Fail2ban s’appuie sur la bibliothèque Python de systemd. Sur une Debian minimale, installez le paquetpython3-systemd(sudo apt install python3-systemd), sinon le service refusera de démarrer avec ce backend.
Sauvegardez, puis rechargez la configuration :
sudo systemctl reload fail2ban
# ou
sudo fail2ban-client reload
Choisir le firewall (UFW / iptables / nftables)
Vérifiez quel firewall est installé :
sudo ufw status # si actif, privilégier banaction=ufw
which iptables # compat couche iptables-nft possible
which nft # présence de nftables
- Si UFW est votre pare-feu :
# dans [DEFAULT]
banaction = ufw
- Sans UFW, sur systèmes modernes (nftables) :
banaction = nftables-multiport
- Anciennes configs encore basées iptables :
banaction = iptables-multiport
Vérifier que ça fonctionne
- État global :
sudo fail2ban-client status
- Détail du jail SSH :
sudo fail2ban-client status sshd
- Voir les IP bannies, les tentatives récentes, etc. Exemple de sortie :
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| `- Total failed: 12
`- Actions
|- Currently banned: 2
`- Total banned: 4
- Débannir manuellement une IP (ex : 203.0.113.10) :
sudo fail2ban-client set sshd unbanip 203.0.113.10
- Bannir manuellement pour tester :
sudo fail2ban-client set sshd banip 203.0.113.10
- Logs Fail2ban :
sudo journalctl -u fail2ban -e
# ou
sudo tail -f /var/log/fail2ban.log
Ajuster la sensibilité (bantime, findtime, maxretry)
- bantime : durée de ban (ex : 10m, 1h, 24h). Unité : s, m, h, d, w.
- findtime : fenêtre pendant laquelle on compte les échecs.
- maxretry : nombre d’échecs permis dans la fenêtre.
Exemple « plus strict » :
[DEFAULT]
bantime = 1h
findtime = 15m
maxretry = 3
Astuce : mettez des valeurs plus permissives au début pour éviter de vous bannir et ajustez progressivement.
Whitelist: ignorer vos IPs
Ajoutez votre IP publique (ou votre bureau/VPN) dans ignoreip :
ignoreip = 127.0.0.1/8 ::1 198.51.100.42 203.0.113.0/24
Rechargez ensuite Fail2ban.
Jails avancés et notifications
Jail « recidive » (récidivistes)
Le jail recidive bannit plus longtemps les IP qui déclenchent plusieurs bans dans la journée.
[recidive]
enabled = true
# Indispensable si backend=systemd est défini dans [DEFAULT] :
# le backend systemd ignore logpath, on force la lecture du fichier
backend = auto
logpath = /var/log/fail2ban.log
bantime = 1w
findtime = 1d
maxretry = 5
Note : ce jail opère au-dessus des autres jails (il lit le log Fail2ban). Utile en production. Avec
backend = systemden global, Fail2ban lirait le journal et ignoreraitlogpath, d’où lebackend = autodans ce jail.
Protéger Nginx
Plusieurs filtres sont fournis (selon la distribution) : nginx-http-auth, nginx-botsearch, etc. Exemple d’un jail basique :
[nginx-botsearch]
enabled = true
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 10
findtime = 10m
bantime = 1h
Vérifiez que le filtre existe sur votre système :
ls /etc/fail2ban/filter.d/ | grep nginx
Sinon, vous pouvez créer vos propres filtres et jails dans *.local. Testez vos regex avec :
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-botsearch.conf
Notifications email
Vous pouvez recevoir un email lors d’un ban, en utilisant une action prédéfinie (ex : action_mw, action_mwl). Il faut disposer d’un agent de mail (ex : postfix).
Exemple :
[DEFAULT]
destemail = admin@example.com
sender = fail2ban@example.com
action = %(action_mwl)s
Bonnes pratiques
- Toujours utiliser des fichiers
.local, ne pas modifier les.confd’origine. - Recharger la configuration après modification :
sudo fail2ban-client reload. - Tester les filtres avec
fail2ban-regexsi un jail ne matche pas. - Surveiller
journalctl -u fail2banpour les erreurs (permissions de logs, chemins). - Ne mettez pas un gros
bantimeau début, combinez plutôt avecrecidive. - Avec UFW, assurez-vous que les ports légitimes restent ouverts (allow) avant d’activer des jails.