Fail2ban — configuration avancée et filtres personnalisés

09 juin 2026 — par admin_libra

Fail2ban est un outil de prévention des intrusions (IPS) open source incontournable sur les serveurs Linux. Il surveille les fichiers journaux à la recherche de tentatives d’authentification répétées et bloque automatiquement les adresses IP suspectes via le pare-feu système. Si son installation de base protège efficacement SSH, Fail2ban révèle tout son potentiel lorsqu’il est configuré avec des filtres personnalisés et des actions sur mesure.

Dans cet article, nous allons dépasser la configuration minimale pour explorer les mécanismes avancés : création de filtres regex personnalisés, configuration de jails multiples, gestion du backend nftables, et mise en place d’actions d’alerte. Chaque étape est illustrée de commandes concrètes testées sur Debian 12 (Bookworm) et Ubuntu 24.04 LTS.

Que vous administriez un serveur web Nginx, un serveur de messagerie Postfix ou une application maison, les techniques présentées ici vous permettront d’adapter Fail2ban à tout service exposant des journaux système.

Prérequis et installation

Fail2ban est disponible directement dans les dépôts officiels de Debian et Ubuntu :

sudo apt update && sudo apt install -y fail2ban

Vérifier que le service est actif et consulter la version installée :

sudo systemctl is-active fail2ban
fail2ban-client --version

Architecture de configuration

Fail2ban organise sa configuration en couches superposées. Il est impératif de ne jamais modifier les fichiers .conf fournis par le paquet, car ils sont écrasés lors des mises à jour. Créez systématiquement des fichiers .local qui prennent la priorité.

Structure des répertoires

/etc/fail2ban/
├── fail2ban.conf       # config globale du démon (ne pas modifier)
├── fail2ban.local      # vos surcharges globales
├── jail.conf           # jails par défaut (ne pas modifier)
├── jail.local          # vos jails personnalisées
├── filter.d/           # filtres (expressions régulières)
│   ├── sshd.conf
│   └── nginx-http-auth.conf
└── action.d/           # actions de ban/unban
    ├── nftables.conf
    └── iptables.conf

Configuration globale dans jail.local

Créez ou éditez /etc/fail2ban/jail.local avec les paramètres globaux :

[DEFAULT]
# IP et plages à ne jamais bannir
ignoreip = 127.0.0.1/8 ::1 10.0.0.0/8

# Durée de ban (supporte les suffixes : s, m, h, d)
bantime  = 1h

# Fenêtre d'observation
findtime = 10m

# Nombre d'échecs avant bannissement
maxretry = 5

# Backend de journaux (systemd recommandé sur Debian/Ubuntu modernes)
backend = systemd

# Backend pare-feu (nftables recommandé depuis Debian 12 / Ubuntu 22.04)
banaction = nftables[type=multiport]

La valeur bantime = -1 génère un ban permanent. Le paramètre ignoreip accepte les plages CIDR et les noms d’hôtes — indispensable pour éviter de se bannir soi-même.

Jails préconfigurés : SSH, Nginx, Apache

Protéger SSH

Le jail SSH est le plus utilisé. Avec un maxretry réduit à 3 et un ban de 24 heures, il décourage efficacement le bruteforce :

[sshd]
enabled  = true
port     = ssh
filter   = sshd
backend  = systemd
maxretry = 3
bantime  = 24h
findtime = 1h

Protéger Nginx

Nginx dispose de plusieurs filtres prêts à l’emploi. Activez-les dans jail.local :

[nginx-http-auth]
enabled  = true
filter   = nginx-http-auth
port     = http,https
logpath  = /var/log/nginx/error.log
maxretry = 5

[nginx-botsearch]
enabled  = true
filter   = nginx-botsearch
port     = http,https
logpath  = /var/log/nginx/access.log
maxretry = 2
bantime  = 6h

Créer un filtre personnalisé

C’est ici que Fail2ban révèle toute sa puissance. Un filtre est un fichier .conf placé dans /etc/fail2ban/filter.d/ contenant des expressions régulières qui analysent les journaux ligne par ligne.

Structure d’un fichier de filtre

[INCLUDES]
before = common.conf

[Definition]
# Regex de détection (obligatoire)
failregex = expression_reguliere_

# Regex d'exclusion (optionnel)
ignoreregex = expression_a_ignorer

La balise spéciale <HOST> capture automatiquement l’adresse IPv4 ou IPv6 de l’attaquant. Elle est obligatoire dans chaque failregex.

Exemple : filtre WordPress (bruteforce wp-login)

Créez le fichier /etc/fail2ban/filter.d/wordpress-bruteforce.conf :

[INCLUDES]
before = common.conf

[Definition]
failregex = ^ .* "POST /wp-login.php HTTP.*" (200|401|403)
            ^ .* "POST /xmlrpc.php HTTP.*" (200|403)
ignoreregex =

Créez le jail correspondant dans jail.local :

[wordpress-bruteforce]
enabled  = true
filter   = wordpress-bruteforce
port     = http,https
logpath  = /var/log/nginx/access.log
maxretry = 6
findtime = 5m
bantime  = 12h

Exemple : filtre pour une application maison

Supposons qu’une application Python enregistre les échecs d’authentification sous cette forme :

2026-06-01 14:32:11 WARN: Authentication failed for user admin from 198.51.100.42

Créez /etc/fail2ban/filter.d/myapp-auth.conf :

[Definition]
failregex = ^%(__prefix_line)ss*WARN: Authentication failed for user S+ from $
ignoreregex =

Puis le jail associé :

[myapp-auth]
enabled  = true
filter   = myapp-auth
port     = 8080
logpath  = /var/log/myapp/app.log
maxretry = 5
bantime  = 2h

Tester un filtre avec fail2ban-regex

Avant d’activer un filtre en production, validez-le impérativement avec l’outil fail2ban-regex :

# Tester un filtre sur un fichier de log existant
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/wordpress-bruteforce.conf

# Tester une ligne de log directement en ligne de commande
sudo fail2ban-regex 
  '198.51.100.42 - - [01/Jun/2026:14:32:11 +0200] "POST /wp-login.php HTTP/1.1" 200 1234' 
  /etc/fail2ban/filter.d/wordpress-bruteforce.conf

# Vérifier la configuration avant rechargement
sudo fail2ban-client -t

La sortie indique le nombre de correspondances et les IP extraites. Un compteur à zéro signifie que la regex ne correspond pas — ajustez-la avant de continuer. Pensez à activer le mode debug en ajoutant loglevel = DEBUG dans fail2ban.local pour les cas complexes.

Actions personnalisées

Les actions définissent ce qui se passe lorsqu’un seuil est franchi. Elles résident dans /etc/fail2ban/action.d/ et s’articulent en plusieurs phases.

Structure d’une action

[Definition]
actionstart = # Commandes exécutées au démarrage de fail2ban
actionstop  = # Commandes exécutées à l'arrêt
actionban   = # Commande exécutée lors d'un ban
actionunban = # Commande exécutée lors d'un unban

Exemple : notification par e-mail + ban nftables

Créez /etc/fail2ban/action.d/notify-and-ban.conf :

[Definition]
actionban   = nft add element inet fail2ban addr-set {  }
              echo "IP bannie :  (jail: , hostname: )" 
                | mail -s "[Fail2ban] Ban " [email protected]

actionunban = nft delete element inet fail2ban addr-set {  }

Référencez cette action dans votre jail :

[sshd]
enabled   = true
banaction = notify-and-ban

Signalement automatique à AbuseIPDB

Pour signaler automatiquement les IP malveillantes à la base de données AbuseIPDB (nécessite une clé API gratuite) :

[Definition]
actionban = curl -s 
              --form "ip=" 
              --form "categories=18,22" 
              --form "comment=Fail2ban - Jail:  sur libra-linux.com" 
              -H "Key: VOTRE_CLE_API" 
              https://api.abuseipdb.com/api/v2/report

Le jail Recidive : pénaliser les récidivistes

Le jail recidive est l’une des additions les plus efficaces après la configuration de base. Il surveille les propres journaux de Fail2ban et re-banne automatiquement les IP déjà bannies, avec une durée beaucoup plus longue :

[recidive]
enabled   = true
filter    = recidive
logpath   = /var/log/fail2ban.log
banaction = nftables[type=allports]
bantime   = 7d
findtime  = 1d
maxretry  = 3

Avec cette configuration, un attaquant banni 3 fois en 24 heures se retrouve bloqué pendant 7 jours sur tous les ports, quel que soit le service ciblé.

Commandes d’administration essentielles

# Vérifier la configuration avant rechargement (indispensable)
sudo fail2ban-client -t

# Recharger la configuration à chaud
sudo fail2ban-client reload

# Lister les jails actifs et leur statut
sudo fail2ban-client status

# Détails d'un jail spécifique (IP bannies, statistiques)
sudo fail2ban-client status sshd

# Bannir manuellement une IP dans un jail
sudo fail2ban-client set sshd banip 203.0.113.42

# Débannir une IP (utile en cas de faux positif)
sudo fail2ban-client unbanip 203.0.113.42

# Consulter les logs en temps réel
sudo journalctl -u fail2ban -f

# Surveiller les bans actifs
sudo tail -f /var/log/fail2ban.log | grep -E "Ban|Found|Unban"

Bonnes pratiques et pièges courants

  • Toujours tester avec fail2ban-regex avant d’activer un nouveau filtre — une regex mal formée bloque tout le jail.
  • Ajouter votre IP dans ignoreip dès le départ pour éviter l’auto-bannissement pendant les tests.
  • Préférer nftables à iptables sur Debian 12+ et Ubuntu 22.04+ : les performances sont meilleures grâce aux mises à jour atomiques des sets.
  • Activer le jail recidive — c’est l’addition à plus fort retour sur investissement.
  • Monitorer /var/log/fail2ban.log ou l’intégrer dans votre solution de supervision (Graylog, Prometheus) pour détecter les attaques coordonnées.
  • Utiliser des bantime progressifs : commencez par 1h en test, puis montez à 24h ou plus en production pour les services critiques.

À lire également

Références

Index complet

Tous les articles (46)

Date Article Tags
17/06/2026 APT : Guide complet de la gestion des paquets sous Debian et Ubuntu administration apt debian 17/06/2026 SHELL : Guide des commandes les plus usuelles et commandes couteau suisse awk bash commandes 17/06/2026 SUDO : implémentation et sécurisation des accès sur Debian/Ubuntu administration audit authentification 17/06/2026 ProFTPd : authentification MySQL centralisée, FTPs (SSL) et SFTP sur Debian/Ubuntu authentification debian ftp 09/06/2026 Fail2ban — configuration avancée et filtres personnalisés bruteforce debian fail2ban 07/06/2026 Docker : comment récupérer de l'espace disque cache conteneurs debian 07/06/2026 Graylog 7 — Centralisation et analyse de logs : l'alternative à ELK sur Debian/Ubuntu centralisation debian elk 07/06/2026 OpenZFS : tiering avec L2ARC et SLOG pour les workloads mixtes cache l2arc nvme 07/06/2026 Scripting Bash avancé — pièges, bonnes pratiques et optimisation automatisation bash bonnes-pratiques 07/06/2026 AppArmor sur Debian/Ubuntu : profils, modes et confinement applicatif apparmor audit confinement 07/06/2026 Durcissement SSH — au-delà des clés publiques 2fa authentification cryptographie 27/05/2026 LXD 6.x : orchestration de conteneurs Linux avec profils et clustering administration clustering conteneurs 27/05/2026 Keepalived — VIP flottante et load balancing sans matériel dédié debian failover haute-disponibilité 27/05/2026 Btrfs sur Linux — snapshots, sous-volumes et compression en pratique administration btrfs compression 21/05/2026 CVE-2026-42945 (NGINX Rift) : analyse et remédiation sur Debian/Ubuntu cve debian heap-overflow 21/05/2026 Tuning kernel Linux — paramètres sysctl essentiels pour la production debian kernel mémoire 21/05/2026 DRBD : réplication de blocs entre deux serveurs en temps réel cluster debian drbd 15/05/2026 CVE-2026-23918 — vulnérabilité Apache 2.4.66 : analyse et correctifs sur Debian/Ubuntu (hors Debian 11) apache cve debian 15/05/2026 CVE-2026-31431 (Copy Fail) — Analyse et remédiation sur Debian/Ubuntu algif_aead copy-fail cve 12/05/2026 Pacemaker et Corosync — cluster haute disponibilité Linux cluster corosync debian 12/05/2026 WireGuard : monter un VPN mesh entre plusieurs serveurs Linux chiffrement linux mesh 12/05/2026 Netdata — monitoring temps réel sans configuration complexe alertes dashboard linux 12/05/2026 nftables en pratique — remplacer iptables sur Debian/Ubuntu debian firewall iptables 12/05/2026 Podman : alternative rootless à Docker — installation et migration conteneurs docker kubernetes 02/05/2026 Prometheus et Grafana sur Debian — installation, configuration et dashboards pratiques alertmanager dashboard debian 02/05/2026 Ansible : automatiser la gestion de serveurs Linux avec des playbooks administration ansible automation 28/04/2026 ZFS sur Linux : snapshots, clones et RAID-Z en pratique administration compression filesystem 28/04/2026 eBPF sur Linux : observabilité et traçage kernel avec bpftrace et BCC bcc bpftrace diagnostic 23/04/2026 Analyse de la mémoire sur Linux — vmstat, free, smem diagnostic mémoire monitoring 23/04/2026 Sécurité Linux — Firewall iptables et nftables firewall iptables nftables 23/04/2026 ZFS sur Linux — Installation et gestion avancée administration filesystem stockage 23/04/2026 Gestion des services avec systemd sur Debian et Ubuntu administration debian services 23/04/2026 Gestion des ressources cgroups v1/v2 avec LXC cgroups conteneurs lxc 23/04/2026 Centralisation logs avec ELK Stack — Elasticsearch, Kibana, Filebeat elasticsearch elk filebeat 23/04/2026 Supervision avec Zabbix 7.0 LTS sur Debian/Ubuntu debian monitoring supervision 23/04/2026 Plusieurs versions PHP-FPM sur Apache Debian/Ubuntu apache debian php-fpm 23/04/2026 Sécurisation avancée PHP-FPM — Multi-VirtualHosts Apache/Nginx apache nginx php-fpm 23/04/2026 Optimisation PHP-FPM — Guide de tuning d'un pool optimisation performance php-fpm 29/07/2025 Docker sur Debian/Ubuntu : Installation, Configuration et Utilisation conteneurs debian docker 03/07/2025 Serveur VPN WireGuard sous linux réseau sécurité vpn 03/07/2025 Authentification par clé publique sur un serveur SSH authentification cryptographie sécurité 27/06/2025 Surveillance et diagnostic d’un serveur Linux avec vmstat, iotop et htop diagnostic htop monitoring 27/06/2025 Mémoire : Utilisation des Huge Pages et implémentation hugepages mémoire noyau 27/06/2025 Mémoire Swap et paramétrage swappiness mémoire noyau performance 18/06/2025 Installation et Configuration des Conteneurs LXC sur Linux administration conteneurs lxc 18/06/2025 Gestion des journaux avec syslog et journalctl administration journalctl logs