Chaque jour, vos serveurs Linux encaissent des milliers de tentatives de connexion automatisées. SSH, Apache, Nginx, Postfix : chaque service exposé devient une cible pour les bots de force brute. Fail2ban est l’outil standard pour y mettre fin, en analysant vos logs en temps réel et en bannissant automatiquement les IP malveillantes via iptables ou nftables. Ce tutoriel vous guide de l’installation à la configuration avancée, en 12 étapes et 30 minutes.
Fail2ban : qu’est-ce que c’est et pourquoi l’utiliser en 2026
Fail2ban est un système de prévention des intrusions (IPS) écrit en Python, conçu pour surveiller les fichiers journaux de vos services et bloquer automatiquement les hôtes qui présentent des signes d’activité malveillante. La logique est simple : après un nombre configurable de tentatives échouées (maxretry), l’adresse IP source est bannie pour une durée définie (bantime) via une règle de pare-feu.
En 2026, les attaques par force brute contre SSH restent parmi les vecteurs d’intrusion les plus courants selon le rapport de menaces ANSSI (CERTFR-2026-CTI-001). Un serveur exposé sur internet sans protection reçoit en moyenne plusieurs centaines de tentatives de connexion SSH par heure. Fail2ban transforme cette menace constante en une protection automatique, sans intervention manuelle.
La version stable actuelle est la 1.1.0, publiée le 25 avril 2024, qui apporte la compatibilité complète avec Python 3.12 et 3.13. Le projet est maintenu sur GitHub avec plus de 10 000 étoiles et une communauté active.
Ce que Fail2ban protège
| Service | Log surveillé | Filtre intégré | Risque bloqué |
|---|---|---|---|
| SSH (OpenSSH) | /var/log/auth.log | sshd | Brute force, scan de ports |
| Apache HTTP | /var/log/apache2/error.log | apache-auth | Authentification HTTP |
| Nginx | /var/log/nginx/error.log | nginx-http-auth | Auth basique, 400/403 |
| Postfix (SMTP) | /var/log/mail.log | postfix | Spam, relais non autorisés |
| Dovecot (IMAP) | /var/log/mail.log | dovecot | Brute force messagerie |
| WordPress | /var/log/nginx/access.log | nginx-botsearch | Scans wp-login.php |
| Proftpd / vsftpd | /var/log/proftpd/*.log | proftpd | Brute force FTP |
Prérequis avant l’installation
Avant de commencer ce tutoriel, assurez-vous de disposer des éléments suivants :
- Système d’exploitation : Ubuntu 22.04 LTS, Ubuntu 24.04 LTS, Debian 11/12, ou CentOS Stream 9 / AlmaLinux 9
- Python : version 3.10 minimum (3.12 recommandé pour Fail2ban 1.1.0)
- Accès root ou sudo sur la machine
- Pare-feu actif : iptables, nftables ou firewalld selon votre distribution
- Systemd : requis pour l’intégration des journaux systemd (journald)
- Services à protéger : SSH installé et actif (openssh-server)
- Connectivité réseau pour installer les paquets
Important : ne lancez jamais ce tutoriel directement depuis une session SSH sans avoir d’abord configuré votre propre adresse IP en liste blanche (ignoreip). Vous risqueriez de vous bloquer vous-même.
Étape 1 : Installer Fail2ban sur Ubuntu/Debian
Sur les distributions basées sur Debian (Ubuntu 22.04, Ubuntu 24.04, Debian 11, Debian 12), l’installation est directe via APT :
# Mise à jour des dépôts
sudo apt update
# Installation de Fail2ban
sudo apt install -y fail2ban
# Vérification de la version installée
fail2ban-client --version
Exemple de sortie attendue :
Fail2Ban v1.1.0
Copyright (c) 2004-2024 Cyril Jaquier, Fail2Ban Contributors
Copyright of modifications held by their respective authors.
Licensed under the GNU General Public License v2 (GPL-2.0)
Sur CentOS Stream 9 / AlmaLinux 9 / Rocky Linux 9, utilisez le dépôt EPEL :
# Activer le dépôt EPEL
sudo dnf install -y epel-release
# Installer Fail2ban
sudo dnf install -y fail2ban
# Vérifier l'installation
fail2ban-client --version
Étape 2 : Démarrer Fail2ban avec systemd
Fail2ban s’intègre nativement avec systemd pour le démarrage automatique et la surveillance des journaux. Activez et démarrez le service :
# Activer Fail2ban au démarrage
sudo systemctl enable fail2ban
# Démarrer le service
sudo systemctl start fail2ban
# Vérifier l'état du service
sudo systemctl status fail2ban
Sortie attendue (service actif) :
● fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2026-06-17 10:00:00 UTC; 5s ago
Docs: man:fail2ban(1)
Main PID: 12345 (fail2ban-server)
Tasks: 5 (limit: 4915)
Memory: 18.3M
CPU: 154ms
CGroup: /system.slice/fail2ban.service
└─12345 /usr/bin/python3 /usr/bin/fail2ban-server -xf start
Fail2ban consomme environ 18 à 25 Mo de mémoire RAM en fonctionnement normal, avec une charge CPU négligeable sur un serveur standard. Ce profil de ressources le rend adapté à tous les types de serveurs, y compris les VPS d’entrée de gamme à 512 Mo de RAM.
Étape 3 : Comprendre jail.conf et jail.local
Fail2ban utilise une architecture de configuration en deux niveaux, fondamentale à comprendre avant toute modification :
- /etc/fail2ban/jail.conf : fichier de configuration principal géré par le paquet. Ne le modifiez jamais directement. Il sera écrasé lors des mises à jour.
- /etc/fail2ban/jail.local : votre fichier de configuration locale, qui prend la priorité sur
jail.conf. Créez-le vous-même pour vos personnalisations. - /etc/fail2ban/jail.d/ : répertoire pour des fichiers de configuration fragmentés, un par service.
La règle d’or : ne jamais toucher jail.conf, toujours travailler dans jail.local. Cette séparation garantit que vos configurations personnalisées survivent aux mises à jour du paquet.
Inspectez d’abord les paramètres par défaut dans jail.conf pour comprendre la structure :
# Lire la configuration par défaut (sans la modifier)
sudo grep -A 20 '\[DEFAULT\]' /etc/fail2ban/jail.conf | head -30
Les paramètres clés de la section [DEFAULT] sont :
| Paramètre | Valeur par défaut | Description |
|---|---|---|
| bantime | 10m | Durée du bannissement (10 minutes) |
| findtime | 10m | Fenêtre de temps pour comptabiliser les échecs |
| maxretry | 5 | Nombre d’échecs avant bannissement |
| ignoreip | 127.0.0.1/8 ::1 | IPs jamais bannies |
| backend | auto | Mécanisme de surveillance des logs |
| usedns | warn | Résolution DNS pour les hôtes |
| destemail | root@localhost | Email destinataire des alertes |
Étape 4 : Créer votre fichier jail.local
Créez maintenant votre fichier jail.local avec une configuration de base sécurisée. Adaptez l’adresse IP dans ignoreip avec votre propre IP publique avant de sauvegarder :
sudo nano /etc/fail2ban/jail.local
Contenu recommandé pour un serveur de production :
[DEFAULT]
# Votre IP d'administration - ne sera jamais bannie
# Remplacez par votre vraie IP publique
ignoreip = 127.0.0.1/8 ::1 203.0.113.0/24
# Durée de bannissement : 1 heure
bantime = 3600
# Fenêtre de détection : 10 minutes
findtime = 600
# Nombre maximum de tentatives avant bannissement
maxretry = 3
# Backend de surveillance des logs
backend = systemd
# Résolution DNS désactivée pour éviter les délais
usedns = no
# Encodage des logs
logencoding = utf-8
# Action par défaut (ban uniquement, sans email)
action = %(action_)s
[sshd]
enabled = true
port = ssh
filter = sshd
backend = systemd
maxretry = 3
bantime = 3600
findtime = 600
Après avoir sauvegardé le fichier, rechargez Fail2ban pour appliquer les changements :
sudo systemctl restart fail2ban
sudo fail2ban-client status
Étape 5 : Configurer la protection SSH
SSH est le premier service à protéger sur tout serveur exposé à internet. Le filtre intégré sshd analyse /var/log/auth.log (Debian/Ubuntu) ou les journaux systemd pour détecter les tentatives d’authentification échouées.
Vérifiez que le jail SSH est actif et consultez ses statistiques en temps réel :
# Statut général de tous les jails actifs
sudo fail2ban-client status
# Statut détaillé du jail SSH
sudo fail2ban-client status sshd
Sortie typique après quelques minutes de fonctionnement sur un serveur exposé :
Status for the jail: sshd
|- Filter
| |- Currently failed: 3
| |- Total failed: 147
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 12
|- Total banned: 89
`- Banned IP list: 45.33.32.156 198.235.24.22 103.89.91.112 ...
Pour un port SSH non standard (par exemple 2222), modifiez la section [sshd] dans jail.local :
[sshd]
enabled = true
port = 2222
filter = sshd
backend = systemd
maxretry = 3
bantime = 86400
findtime = 3600
Avec bantime = 86400 (24 heures) et maxretry = 3, un attaquant qui échoue 3 fois en 1 heure est bloqué pendant 24 heures. C’est le réglage recommandé pour les serveurs de production soumis à des attaques fréquentes.
Étape 6 : Protéger Apache et Nginx
Les serveurs web sont exposés à des scans permanents : tentatives de connexion à des interfaces d’administration, exploitation de wp-login.php, recherche de fichiers sensibles. Fail2ban dispose de filtres intégrés pour Apache et Nginx.
Protection Apache
Ajoutez ces jails dans votre jail.local pour une protection Apache multicouche :
[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/error.log
maxretry = 5
bantime = 3600
[apache-noscript]
enabled = true
port = http,https
filter = apache-noscript
logpath = /var/log/apache2/error.log
maxretry = 6
bantime = 86400
[apache-overflows]
enabled = true
port = http,https
filter = apache-overflows
logpath = /var/log/apache2/error.log
maxretry = 2
bantime = 86400
[apache-nohome]
enabled = true
port = http,https
filter = apache-nohome
logpath = /var/log/apache2/error.log
maxretry = 2
bantime = 86400
Protection Nginx
Pour Nginx, les jails essentiels sont :
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
bantime = 3600
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2
bantime = 86400
findtime = 300
Le filtre nginx-botsearch est particulièrement efficace pour bloquer les scanners qui recherchent des fichiers wp-login.php, xmlrpc.php, phpMyAdmin et autres cibles classiques. Avec maxretry = 2 et findtime = 300 (5 minutes), même un premier scan agressif déclenche un bannissement immédiat.
Étape 7 : Choisir entre nftables, iptables et firewalld
Fail2ban applique les bannissements via des règles de pare-feu. En 2026, trois backends sont couramment utilisés selon la distribution :
| Backend | Distribution typique | Action Fail2ban | Recommandation |
|---|---|---|---|
| iptables | Ubuntu 22.04, Debian 11 | iptables-multiport | Compatible universel |
| nftables | Ubuntu 24.04, Debian 12 | nftables-multiport | Recommandé (moderne) |
| firewalld | CentOS 9, AlmaLinux 9 | firewallcmd-rich-rules | RHEL/CentOS |
Pour vérifier quel backend est disponible sur votre système :
# Vérifier iptables
which iptables && iptables --version
# Vérifier nftables
which nft && nft --version
# Vérifier firewalld
systemctl is-active firewalld
Pour forcer l’utilisation de nftables sur Ubuntu 24.04, configurez l’action dans jail.local :
[DEFAULT]
# ...paramètres précédents...
# Forcer nftables comme backend d'action
banaction = nftables-multiport
banaction_allports = nftables-allports
Sur les systèmes avec firewalld (Red Hat, CentOS, AlmaLinux) :
[DEFAULT]
banaction = firewallcmd-rich-rules[actiontype=]
banaction_allports = firewallcmd-allports
Pour vérifier qu’une règle de bannissement a bien été appliquée via iptables après qu’une IP a été bannie :
sudo iptables -L f2b-sshd -n --line-numbers
Étape 8 : Activer le jail recidive pour les récidivistes
Le jail recidive est une fonctionnalité avancée qui surveille le journal de Fail2ban lui-même. Quand une IP est bannie plusieurs fois dans d’autres jails, recidive lui applique un bannissement beaucoup plus long. C’est le deuxième niveau de défense, idéal pour les attaquants persistants.
Ajoutez cette section dans jail.local :
[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
action = %(action_mwl)s
bantime = 604800
findtime = 86400
maxretry = 5
Avec cette configuration, une IP bannie 5 fois en 24 heures dans n’importe quel jail actif sera ensuite bannie pour 7 jours (604 800 secondes). Les IPs les plus agressives accumulent rapidement ces bans. L’action %(action_mwl)s bannit l’IP, envoie un email avec les lignes de log concernées et effectue un whois de l’adresse IP.
Pour les environnements particulièrement ciblés, certains administrateurs configurent bantime = 2592000 (30 jours) pour les récidivistes les plus agressifs, comme dans l’exemple suivant pour un jail SSH ultra-strict :
[sshd-aggressive]
enabled = true
filter = sshd
backend = systemd
port = ssh
maxretry = 1
bantime = 2592000
findtime = 86400
action = %(action_mwl)s
Notez que maxretry = 1 est une approche radicale : la moindre tentative échouée sur SSH déclenche un bannissement de 30 jours. Adaptez selon votre tolérance aux faux positifs.
Étape 9 : Configurer les notifications par email
Fail2ban peut envoyer des alertes par email à chaque bannissement ou débannissement. Pour l’activer, votre serveur doit disposer d’un MTA (mail transfer agent) fonctionnel, comme postfix ou sendmail. Vérifiez que sendmail est disponible :
which sendmail && sendmail --version 2>&1 | head -3
Configurez les emails dans jail.local :
[DEFAULT]
# Email de l'expéditeur (adapter à votre domaine)
sender = [email protected]
# Email destinataire des alertes
destemail = [email protected]
# MTA utilisé pour l'envoi
mta = sendmail
# Action avec email + whois lors d'un ban
action = %(action_mwl)s
Les actions disponibles pour l’email sont :
%(action_)s: ban uniquement, pas d’email%(action_m)s: ban + email de notification simple%(action_mw)s: ban + email + informations whois%(action_mwl)s: ban + email + whois + lignes de log pertinentes
Pour un jail spécifique avec des emails uniquement pour les bannissements SSH (et pas pour les tentatives web mineures), appliquez l’action selectively :
[sshd]
enabled = true
port = ssh
filter = sshd
backend = systemd
maxretry = 3
bantime = 3600
action = %(action_mwl)s
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2
bantime = 86400
# Pas d'email pour ce jail (trop de volume)
action = %(action_)s
Étape 10 : Gérer les bannissements manuellement
La commande fail2ban-client est votre interface principale pour gérer les bannissements en temps réel, sans avoir à redémarrer le service.
Commandes essentielles pour la gestion quotidienne :
# Lister tous les jails actifs
sudo fail2ban-client status
# Voir les IPs bannies dans le jail SSH
sudo fail2ban-client status sshd
# Débannir une IP spécifique du jail SSH
sudo fail2ban-client set sshd unbanip 203.0.113.42
# Bannir manuellement une IP dans le jail SSH
sudo fail2ban-client set sshd banip 198.51.100.10
# Recharger la configuration sans redémarrage
sudo fail2ban-client reload
# Recharger un jail spécifique seulement
sudo fail2ban-client reload sshd
# Vérifier si une IP est bannie (dans tous les jails)
sudo fail2ban-client banned 198.51.100.10
# Voir le log de Fail2ban en temps réel
sudo tail -f /var/log/fail2ban.log
Exemple de sortie du log en temps réel lors d’une attaque :
2026-06-17 10:15:32,421 fail2ban.filter [12345]: INFO [sshd] Found 45.33.32.156 - 2026-06-17 10:15:32
2026-06-17 10:15:34,102 fail2ban.filter [12345]: INFO [sshd] Found 45.33.32.156 - 2026-06-17 10:15:34
2026-06-17 10:15:35,887 fail2ban.filter [12345]: INFO [sshd] Found 45.33.32.156 - 2026-06-17 10:15:35
2026-06-17 10:15:35,901 fail2ban.actions [12345]: NOTICE [sshd] Ban 45.33.32.156
2026-06-17 10:20:35,103 fail2ban.actions [12345]: NOTICE [sshd] Unban 45.33.32.156
Étape 11 : Créer un filtre personnalisé
Fail2ban inclut des dizaines de filtres prédéfinis dans /etc/fail2ban/filter.d/, mais vous pouvez en créer de nouveaux pour vos applications spécifiques. Les filtres utilisent des expressions régulières Python pour identifier les lignes de log malveillantes.
Exemple : créer un filtre pour protéger une application Node.js qui enregistre les tentatives d’authentification échouées dans un format personnalisé. Supposons que les logs contiennent des lignes comme :
2026-06-17 10:15:32 AUTH_FAIL ip=203.0.113.42 user=admin reason=bad_password
Créez le fichier filtre :
sudo nano /etc/fail2ban/filter.d/nodejs-auth.conf
[Definition]
# Filtre pour les échecs d'authentification Node.js
failregex = ^.* AUTH_FAIL ip= .*$
# Lignes à ignorer (succès, redémarrages)
ignoreregex = ^.* AUTH_SUCCESS .*$
Puis ajoutez le jail correspondant dans jail.local :
[nodejs-auth]
enabled = true
filter = nodejs-auth
logpath = /var/log/myapp/auth.log
maxretry = 5
bantime = 3600
findtime = 300
port = 3000
Testez votre filtre avec fail2ban-regex avant de l’activer en production :
# Tester le filtre contre un fichier de log existant
sudo fail2ban-regex /var/log/myapp/auth.log /etc/fail2ban/filter.d/nodejs-auth.conf
# Tester avec une ligne de log directement
sudo fail2ban-regex "2026-06-17 10:15:32 AUTH_FAIL ip=203.0.113.42 user=admin reason=bad_password" /etc/fail2ban/filter.d/nodejs-auth.conf
Sortie attendue si le filtre fonctionne :
Running tests
=============
Use failregex filter file : nodejs-auth, basedir: /etc/fail2ban
Use log file : 2026-06-17 10:15:32 AUTH_FAIL ip=203.0.113.42 user=admin reason=bad_password
Use encoding : UTF-8
Results
=======
Failregex: 1 total
|- #) [# of hits] regular expression
| 1) [1] ^.* AUTH_FAIL ip= .*$
`-
Ignoreregex: 0 total
Date template hits:
|- [# of hits] date format
| [1] ExYear(?PYear)-(?PMonth)-(?PDay)(?:T| +)...
`-
Lines: 1 lines, 0 ignored, 1 matched, 0 missed
Étape 12 : Bannissements progressifs avec bantime.increment
La fonctionnalité bantime.increment permet d’allonger automatiquement la durée de bannissement à chaque récidive d’une même IP. C’est l’une des évolutions les plus importantes de Fail2ban, qui transforme un outil de protection réactif en un système adaptatif.
Activez les bannissements progressifs dans jail.local :
[DEFAULT]
# Activer les bannissements progressifs
bantime.increment = true
# Durée de base du premier bannissement
bantime = 600
# Multiplicateur appliqué à chaque récidive (x2 par défaut)
bantime.factor = 2
# Durée maximum du bannissement (1 semaine)
bantime.maxtime = 604800
# Formule de calcul : base * factor^(nombre de bans précédents)
# 1er ban : 600s (10 min)
# 2e ban : 1200s (20 min)
# 3e ban : 2400s (40 min)
# 4e ban : 4800s (1h20)
# 5e ban : 9600s (2h40)
# ... jusqu'au maximum de 604800s (7 jours)
# Utiliser la base de données SQLite pour mémoriser les récidives
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
dbpurgeage = 86400
Cette configuration transforme Fail2ban en un système d’apprentissage simple : les attaquants qui reviennent régulièrement font face à des bans exponentiellement plus longs. La base de données SQLite conserve l’historique des bannissements pour que la mémoire persiste même après un redémarrage du service.
5 pièges fréquents (et comment les éviter)
Ces erreurs reviennent systématiquement lors de la configuration de Fail2ban. Identifiez-les avant qu’elles ne causent des problèmes en production.
Piège 1 : Se bloquer soi-même via SSH
Symptôme : vous perdez l’accès SSH à votre propre serveur après avoir configuré Fail2ban.
Cause : votre IP d’administration n’est pas dans ignoreip, et vous avez mal tapé votre mot de passe 3 fois pendant la configuration.
Solution préventive : avant d’activer Fail2ban, ajoutez impérativement votre IP publique dans ignoreip :
# Trouver votre IP publique depuis le serveur
curl -s ifconfig.me
# Puis dans jail.local :
ignoreip = 127.0.0.1/8 ::1 VOTRE_IP_ICI
Solution curative : si vous êtes bloqué, accédez au serveur via la console KVM/IPMI de votre hébergeur, ou via VNC, puis débannissez votre IP depuis le shell local.
Piège 2 : Modifier jail.conf directement
Symptôme : vos configurations disparaissent après une mise à jour de Fail2ban.
Cause : vous avez modifié /etc/fail2ban/jail.conf au lieu de créer jail.local.
Solution : toujours créer un fichier jail.local pour vos personnalisations. La règle est absolue.
Piège 3 : Utiliser le mauvais backend de log
Symptôme : Fail2ban ne détecte aucune tentative malgré des attaques visibles dans les logs.
Cause : le paramètre backend est mal configuré. Sur Ubuntu 22.04+ avec systemd, les logs SSH ne sont pas dans /var/log/auth.log par défaut, mais dans le journal systemd.
Solution : utilisez backend = systemd et vérifiez avec :
# Vérifier les logs SSH dans journald
sudo journalctl -u sshd --since "1 hour ago" | grep "Failed password" | head -5
# Si des lignes apparaissent, journald fonctionne pour SSH
# Dans jail.local :
[sshd]
backend = systemd
Piège 4 : Regex de filtre incorrect (faux négatifs)
Symptôme : un jail est actif mais ne banne jamais personne, même lors d’attaques évidentes.
Cause : la regex failregex ne correspond pas au format de log réel de votre version du service.
Solution : testez toujours votre filtre avec fail2ban-regex avant de l’activer :
# Tester le filtre sshd contre les vrais logs
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf --print-all-matched | tail -20
Piège 5 : bantime trop court face aux botnets distribués
Symptôme : Fail2ban banne des centaines d’IPs différentes mais les attaques continuent sans relâche.
Cause : les botnets modernes utilisent des milliers d’IPs rotatives. Un bantime de 10 minutes est inefficace face à un botnet de 50 000 IPs qui revient avec une IP différente toutes les 15 minutes.
Solution : combinez un bantime long (24h minimum), le jail recidive, et bantime.increment = true. Envisagez également de bloquer des plages d’ASN entières pour les attaquants récurrents.
8 problèmes de dépannage courants
| Problème | Diagnostic | Solution |
|---|---|---|
| fail2ban ne démarre pas | sudo journalctl -u fail2ban -n 50 | Vérifier la syntaxe de jail.local (souvent une virgule ou espace manquant) |
| Jail inactif après reload | sudo fail2ban-client status | Vérifier enabled = true dans le jail et redémarrer (pas juste reload) |
| Aucun ban détecté | sudo fail2ban-regex /var/log/auth.log sshd | Vérifier que le filtre correspond aux logs, changer backend |
| IP bannie mais toujours accessible | sudo iptables -L f2b-sshd -n | Vérifier la chaîne iptables, tester avec nftables si disponible |
| Se retrouver banni | Console KVM de l’hébergeur | sudo fail2ban-client set sshd unbanip MON_IP |
| Trop de faux positifs | sudo tail -f /var/log/fail2ban.log | Augmenter maxretry, réduire findtime, ajouter l’IP dans ignoreip |
| Fail2ban consomme trop de CPU | top -p $(pgrep fail2ban-server) | Réduire le nombre de jails actifs ou utiliser backend systemd |
| Base de données SQLite corrompue | sudo sqlite3 /var/lib/fail2ban/fail2ban.sqlite3 ".tables" | Arrêter fail2ban, supprimer le .sqlite3, redémarrer |
Pour un diagnostic complet de Fail2ban, activez le mode debug temporairement :
# Arrêter le service
sudo systemctl stop fail2ban
# Lancer en mode debug (foreground)
sudo fail2ban-server -f -x -l DEBUG
# Dans un autre terminal, surveiller les sorties
# Appuyer sur Ctrl+C pour arrêter, puis relancer normalement :
sudo systemctl start fail2ban
Configuration complète pour un serveur de production
Voici un fichier jail.local complet et opérationnel pour un serveur web de production hébergeant SSH, Nginx et WordPress. Copiez-le, adaptez l’adresse IP et le domaine, et vous disposerez d’une protection multi-couches immédiatement fonctionnelle :
[DEFAULT]
# Remplacez par votre IP d'administration
ignoreip = 127.0.0.1/8 ::1 203.0.113.0/24
# Bannissements progressifs
bantime = 3600
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 604800
# Fenêtre et seuil de détection
findtime = 600
maxretry = 3
# Backend systemd (recommandé Ubuntu 22.04+)
backend = systemd
# Pas de résolution DNS pour les performances
usedns = no
# Base de données pour la persistance des bans
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
dbpurgeage = 86400
# Action par défaut sans email
action = %(action_)s
# --- SSH ---
[sshd]
enabled = true
port = ssh
filter = sshd
backend = systemd
maxretry = 3
bantime = 3600
action = %(action_mwl)s
destemail = [email protected]
sender = [email protected]
# --- NGINX ---
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
bantime = 3600
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2
bantime = 86400
findtime = 300
# --- RÉCIDIVISTES ---
[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
bantime = 604800
findtime = 86400
maxretry = 5
Conseils avancés pour aller plus loin
Une fois la configuration de base en place, ces optimisations avancées renforceront significativement la protection de votre serveur.
Intégrer des listes de blocage externes (threatfeeds) : combinez Fail2ban avec des listes de menaces connues comme AbuseIPDB. Un script cron peut télécharger quotidiennement les IP à fort score de menace et les injecter directement dans un jail Fail2ban via fail2ban-client set jail banip.
Surveiller les métriques avec Prometheus : l’exporteur officiel fail2ban-exporter expose des métriques Prometheus sur le nombre de bans actifs, le total de bans par jail, et la durée moyenne des bannissements. C’est particulièrement utile pour Grafana et les tableaux de bord de sécurité.
Partager les bannissements entre plusieurs serveurs : si vous gérez une infrastructure multi-serveurs, utilisez une base de données MySQL ou PostgreSQL partagée à la place de SQLite. Configurez dbfile = mysql://user:pass@host/fail2ban pour que tous vos serveurs partagent le même historique de récidives.
Bloquer les scanners Shodan et Censys : créez un jail spécifique pour bannir automatiquement les plages d’IP connues des scanners légaux comme Shodan (plages 198.20.0.0/16) qui, bien qu’inoffensifs, génèrent du bruit dans vos logs et peuvent masquer de vraies attaques.
Combiner avec fail2ban-geoip-stats : l’outil fail2ban-geoip-stats génère des statistiques géographiques des IP bannies et produit des rapports HTML hebdomadaires. Il permet d’identifier les pays d’origine des attaques les plus fréquentes pour affiner votre stratégie de blocage.
Questions fréquentes (FAQ)
Fail2ban ralentit-il mon serveur ?
Non. En fonctionnement normal, Fail2ban consomme entre 18 et 25 Mo de RAM et moins de 1 % de CPU. L’impact sur les performances est négligeable, même sur un VPS à 1 vCPU. Le seul scénario où la charge augmente est lors d’attaques massives générant des milliers de lignes de log par seconde.
Faut-il utiliser Fail2ban avec un pare-feu dédié comme UFW ?
Oui, les deux sont complémentaires. UFW (ou firewalld sur RHEL) gère les règles statiques permanentes : ports ouverts, flux autorisés. Fail2ban gère les règles dynamiques temporaires : bannissements basés sur le comportement. Sur Ubuntu 22.04+, UFW et Fail2ban coexistent sans conflit, mais vérifiez que les deux n’entrent pas en conflit sur la chaîne INPUT d’iptables.
Quelle est la différence entre bantime, findtime et maxretry ?
findtime est la fenêtre de temps (en secondes) pendant laquelle Fail2ban compte les tentatives échouées. maxretry est le nombre maximum d’échecs autorisés dans cette fenêtre avant un bannissement. bantime est la durée du bannissement une fois déclenché. Exemple : findtime=600, maxretry=5, bantime=3600 signifie que 5 échecs en 10 minutes entraînent un bannissement d’1 heure.
Comment vérifier que Fail2ban fonctionne réellement ?
Utilisez sudo fail2ban-client status sshd pour voir le nombre de bans actifs et le total de tentatives détectées. Surveillez /var/log/fail2ban.log pour les entrées NOTICE de type “Ban [IP]”. Si le “Total failed” augmente et que des “Ban” apparaissent, Fail2ban fonctionne correctement.
Peut-on utiliser Fail2ban avec IPv6 ?
Oui. Fail2ban supporte nativement IPv4 et IPv6. Assurez-vous que votre action iptables est configurée pour les deux protocoles, ou utilisez l’action iptables-allports combinée avec ip6tables. Avec nftables, le support IPv6 est natif et transparent.
Fail2ban suffit-il pour sécuriser un serveur ?
Non. Fail2ban est un outil de mitigation, pas une solution de sécurité complète. Il complète mais ne remplace pas : l’authentification par clé SSH (désactiver les mots de passe), les mises à jour de sécurité régulières, un pare-feu strict (UFW/firewalld), la surveillance des vulnérabilités avec des outils comme Nmap, et la gestion des accès par le principe du moindre privilège.
Fail2ban est-il compatible avec les conteneurs Docker ?
Avec précaution. Fail2ban doit être installé sur l’hôte Docker, pas dans un conteneur. Il doit accéder aux logs des conteneurs (montés via volumes) et aux tables iptables de l’hôte. Les règles Fail2ban n’affectent pas les règles iptables de Docker par défaut, donc une configuration spécifique est nécessaire pour que les bans bloquent également le trafic vers les ports mappés.
Comment migrer de iptables vers nftables avec Fail2ban ?
Installez nftables (sudo apt install nftables), activez le service (sudo systemctl enable nftables), puis dans jail.local changez banaction = nftables-multiport et banaction_allports = nftables-allports. Redémarrez Fail2ban. Vérifiez les règles créées avec sudo nft list ruleset.
Couverture associée
Articles connexes
- OpenSSL : clés et certificats en 12 étapes – Générer des clés privées et des certificats TLS/SSL avec OpenSSL
- Nmap : scanner un réseau en 12 étapes – Identifier les ports ouverts et vulnérabilités sur votre infrastructure
- ssh-keygen : clé SSH en 12 étapes, 20 min – Sécuriser SSH avec des clés cryptographiques plutôt que des mots de passe
- OAuth2 en Node.js : flux sécurisé en 12 étapes – Implémenter l’authentification moderne dans vos applications web
- Faille IDOR : 31 millions de comptes publics exposés – Comprendre les vulnérabilités d’accès aux objets pour mieux les prévenir




