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 :

  1. Surveillance des journaux — Le daemon logtarget de Fail2Ban surveille les fichiers journaux (par exemple /var/log/auth.log, /var/log/nginx/error.log) en utilisant inotify ou le polling.
  2. 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.
  3. Vérification du seuil — Une fois que le compteur atteint maxretry dans la fenêtre findtime, l’IP est considérée hostile.
  4. 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 bantime secondes.

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 à ignoreip avant 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.sqlite3 pour 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 ignoreip pé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 — utilisez jail.local ou des fichiers drop-in dans jail.d/
  • Configurez toujours ignoreip avec votre propre IP avant d’activer des jails stricts
  • Le bannissement progressif (bantime.increment) rend les attaquants persistants effectivement permanents
  • Utilisez fail2ban-regex pour tester et valider les patterns de filtres avant le déploiement

Articles Connexes