TL;DR — Résumé Rapide
Fail2Ban guide complet : installation, jails SSH, bannissement progressif, filtres personnalisés, protection Nginx/Apache/mail et intégration Cloudflare Linux.
Chaque serveur Linux exposé à internet est sous attaque constante. Des bots automatisés parcourent l’intégralité de l’espace d’adresses IPv4 en quelques heures, testant des milliers de combinaisons nom d’utilisateur/mot de passe contre SSH et d’autres services. Fail2Ban est un framework de prévention d’intrusion basé sur les journaux qui détecte ces attaques en temps réel et ordonne au pare-feu de bloquer les IPs offensantes — automatiquement, sans intervention manuelle. Ce guide couvre la configuration complète de Fail2Ban : installation, configuration des jails SSH, bannissement progressif, création de filtres personnalisés, protection pour Nginx, Apache et serveurs mail, et intégration avec l’API Cloudflare.
Prérequis
Avant de commencer, assurez-vous d’avoir :
- Un serveur Linux sous Ubuntu 20.04/22.04/24.04, Debian 11/12 ou RHEL/Rocky/AlmaLinux 8/9
- Accès root ou sudo
- Accès SSH au serveur
- iptables, nftables ou firewalld gérant votre pare-feu
- Familiarité de base avec la gestion des services systemd
Fonctionnement de Fail2Ban
Fail2Ban opère sur un cycle surveiller → correspondre → bannir :
- Surveillance des journaux — Le daemon
logtargetde Fail2Ban surveille les fichiers journaux (par exemple/var/log/auth.log,/var/log/nginx/error.log) en utilisant inotify ou le polling. - Correspondance regex — Chaque jail référence un filtre contenant un ou plusieurs patterns
failregex. Quand une ligne de journal correspond, Fail2Ban incrémente un compteur d’échecs pour l’IP source. - Vérification du seuil — Une fois que le compteur atteint
maxretrydans la fenêtrefindtime, l’IP est considérée hostile. - Bannissement par le pare-feu — Fail2Ban appelle une action (typiquement iptables, nftables ou firewalld) pour insérer une règle DROP pour l’IP offensante. La règle est automatiquement supprimée après
bantimesecondes.
Installation
Ubuntu / Debian
sudo apt update
sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban
RHEL / Rocky / AlmaLinux
Le dépôt EPEL est requis :
sudo dnf install epel-release -y
sudo dnf install fail2ban -y
sudo systemctl enable --now fail2ban
Sur les systèmes de la famille RHEL, firewalld est le backend par défaut :
sudo dnf install fail2ban-firewalld -y
Configuration du Jail SSH
N’éditez jamais /etc/fail2ban/jail.conf directement — il est écrasé lors des mises à jour. Créez plutôt vos substitutions dans /etc/fail2ban/jail.local :
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Un jail SSH complet et prêt pour la production :
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
backend = systemd
maxretry = 4
findtime = 1h
bantime = 24h
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
Paramètres clés expliqués :
| Paramètre | Valeur | Signification |
|---|---|---|
maxretry | 4 | Tentatives échouées avant le bannissement |
findtime | 1h | Fenêtre pour compter les échecs |
bantime | 24h | Durée du bannissement de l’IP |
ignoreip | Liste CIDR | IPs qui ne sont jamais bannies |
backend | systemd | Lire les journaux depuis journald |
Avertissement : Ajoutez toujours votre propre IP ou sous-réseau de gestion à
ignoreipavant d’activer des jails stricts. Se bloquer sur une VM cloud nécessite un accès console pour récupérer l’accès.
Bannissement Progressif
Ajoutez ces paramètres à [DEFAULT] dans jail.local :
[DEFAULT]
bantime.increment = true
bantime.multipliers = 1 5 30 60 300 720 1440 2880
bantime.maxtime = 5w
bantime.overalljails = true
Avec la séquence de multiplicateurs 1 5 30 60 300 720 1440 2880 et un bantime de base de 10 minutes :
- 1er bannissement : 10 minutes
- 2e bannissement : 50 minutes
- 3e bannissement : 5 heures
- 4e bannissement : 10 heures
- 5e bannissement : ~2 jours
Création de Filtres Personnalisés
Les filtres se trouvent dans /etc/fail2ban/filter.d/. Exemple pour une API Node.js qui journalise :
2026-03-22 14:05:33 [AUTH FAIL] 203.0.113.42 - Invalid token on /api/v1/login
Créez /etc/fail2ban/filter.d/myapp-auth.conf :
[Definition]
failregex = ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} \[AUTH FAIL\] <HOST> -
ignoreregex =
Testez votre regex avant d’activer :
sudo fail2ban-regex /var/log/myapp/app.log /etc/fail2ban/filter.d/myapp-auth.conf
Protection Nginx
[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 3
bantime = 1h
[nginx-botsearch]
enabled = true
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 2
bantime = 24h
[nginx-limit-req]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 10
bantime = 10m
Jails Apache et Serveur Mail
Apache
[apache-auth]
enabled = true
port = http,https
logpath = /var/log/apache2/error.log
maxretry = 3
[apache-badbots]
enabled = true
port = http,https
logpath = /var/log/apache2/access.log
bantime = 48h
Postfix / Dovecot
[postfix]
enabled = true
port = smtp,465,submission
logpath = /var/log/mail.log
maxretry = 3
[dovecot]
enabled = true
port = pop3,pop3s,imap,imaps,submission,465,sieve
logpath = /var/log/mail.log
maxretry = 3
bantime = 12h
Gestion des Bannissements avec fail2ban-client
# Afficher tous les jails actifs
sudo fail2ban-client status
# Afficher les IPs bannies dans un jail spécifique
sudo fail2ban-client status sshd
# Bannir manuellement une IP
sudo fail2ban-client set sshd banip 203.0.113.42
# Débannir une IP
sudo fail2ban-client set sshd unbanip 203.0.113.42
# Recharger la configuration sans redémarrage
sudo fail2ban-client reload
# Voir toutes les IPs bannies dans tous les jails
sudo fail2ban-client banned
Configuration des Actions
[DEFAULT]
# iptables (classique, le plus compatible)
banaction = iptables-multiport
# nftables (recommandé pour les distros modernes)
banaction = nftables-multiport
# firewalld (RHEL/Rocky)
banaction = firewallcmd-ipset
# Envoyer une notification par e-mail lors du bannissement
action = %(action_mwl)s
Test des Filtres avec fail2ban-regex
# Tester contre un fichier journal
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
# Tester avec une ligne de journal spécifique
sudo fail2ban-regex "Mar 22 14:05:33 server sshd[12345]: Failed password for root from 203.0.113.42 port 54321 ssh2" sshd
Intégration Cloudflare
Option 1 — Restaurer les IPs réelles via l’en-tête CF-Connecting-IP :
set_real_ip_from 103.21.244.0/22;
real_ip_header CF-Connecting-IP;
Option 2 — Bannir au niveau de la périphérie Cloudflare en utilisant l’action cloudflare :
[DEFAULT]
cftoken = VOTRE_TOKEN_API_CLOUDFLARE
cfzoneid = VOTRE_ZONE_ID
[nginx-botsearch]
enabled = true
action = %(action_)s
cloudflare[cftoken="%(cftoken)s", cfzoneid="%(cfzoneid)s"]
Fail2Ban vs Alternatives
| Outil | Mécanisme | Langage | Portée | Communauté |
|---|---|---|---|---|
| Fail2Ban | Regex journaux + pare-feu local | Python | Serveur local | Non |
| CrowdSec | Analyse comportementale + listes partagées | Go | Multi-serveur | Oui |
| DenyHosts | Uniquement SSH /etc/hosts.deny | Python | SSH uniquement | Optionnel |
| SSHGuard | Daemon C, multi-backend | C | Services limités | Non |
Conseils de Durcissement en Production
- Changez le port SSH du 22 vers un port non standard pour réduire le bruit de scan automatisé
- Définissez
bantimeà au moins 24h pour SSH - Surveillez le journal Fail2Ban dans
/var/log/fail2ban.log - Sauvegardez
/var/lib/fail2ban/fail2ban.sqlite3pour préserver l’historique des bannissements - Combinez avec la limitation de débit UFW (
sudo ufw limit ssh) pour une défense en profondeur - Auditez votre liste
ignoreippériodiquement
Résumé
Fail2Ban offre une protection robuste et automatisée contre les attaques par force brute pour tout serveur Linux exposant des services à internet. Points clés :
- Fail2Ban surveille les journaux, fait correspondre les patterns d’échec avec des regex et ajoute des règles de pare-feu pour bloquer les IPs offensantes
- N’éditez jamais
jail.conf— utilisezjail.localou des fichiers drop-in dansjail.d/ - Configurez toujours
ignoreipavec votre propre IP avant d’activer des jails stricts - Le bannissement progressif (
bantime.increment) rend les attaquants persistants effectivement permanents - Utilisez
fail2ban-regexpour tester et valider les patterns de filtres avant le déploiement