Fail2ban
- Qu’est-ce que Fail2ban ?
- Fonctionnalités principales de Fail2ban
- Installation de Fail2ban
- Configuration de Fail2ban pour les services actifs
- Activer la prison SSH (sshd)
- La Prison spéciale
- Exemple Fail2ban pour nginx
- Récidive
- Installation automatique
- Commandes nftables et fail2ban
Qu’est-ce que Fail2ban ?
Fail2ban est un logiciel de sécurité destiné à prévenir les attaques par force brute en bloquant temporairement les adresses IP suspectes. Il analyse les journaux des services pour détecter des schémas d’échecs d’authentification répétés et autres comportements suspects, pus utilise des règles nftables pour bannir temporairement ces adresses IP.
Fonctionnalités principales de Fail2ban
- Surveillance des journaux : fail2ban surveille les fichiers de journaux de divers services (SSH, FTP, HTTP, etc.) pour détecter des tentatives de connexion échouées répétées
- Bannissement temporaire : lorsque fail2ban détecte un nombre prédéfini de tentatives échouées depuis une même IP, il bannit cette IP pour une période définie
- Flexibilité et extensibilité : fail2ban est hautement configurable et peut être étendu pour surveiller presque n’importe quel service à travers des fichiers de configuration personnalisés et des filtres regex
- Actions de bannissement : fail2ban peut utiliser différentes actions de bannissement, telles que la mise à jour des règles nftables, la modification des règles hosts.deny, ou l’envoi de notifications par email
Installation de Fail2ban
Méthode N°1
Installation de Fail2ban et nftables via les paquets officiels :
sudo apt install -y fail2ban nftables
Méthode N°2 : via les sources
Installation de Fail2ban via les sources du dépôt GitHub :
git clone https://github.com/fail2ban/fail2ban.git
cd fail2ban
sudo python setup.py install
On vérifie que Fail2ban s’est correctement installé :
fail2ban-client -h
Configuration de Fail2ban pour les services actifs
On démarre le service :
systemctl start fail2ban
On active le démarrage automatique :
systemctl enable fail2ban
On vérifie que le service fonctionne :
systemctl status fail2ban
Par défaut, Fail2ban utilise les fichiers /etc/fail2ban/jail.conf et /etc/fail2ban/jail.d/defaults-debian.conf qui contient les réglages globaux et les définitions des prisons (jails). Ce fichier ne doit jamais être modifié car il serait écrasé lors d’une mise à jour de Fail2ban.
Par défaut, fail2ban utilise nftables-multiport.
On vérifie que le fichier existe :
sudo cat /etc/fail2ban/action.d/nftables-multiport.conf
La méthode standard consiste à créer un fichier de configuration local qui surchargera uniquement les paramètres qu’on souhaite modifier :
sudo nano /etc/fail2ban/jail.local
On va configurer le fichier jail.local et utiliser les paramètres par défaut les plus importants pour définir la politique de bannissement pour toutes les prisons qui seront activées :
[DEFAULT]
backend = systemd
banaction = nftables-multiport
bantime = 1h
findtime = 10m
maxretry = 3
# On peut remplacer 192.168.1.0/24 par la plage d’IP de votre réseau local, si applicable
ignoreip = 127.0.0.1/8 192.168.1.0/24 ::1
# bannissement progressif
bantime.increment = true
bantime.factor = 2
bantime.max = 1w
# IP autorisées
ignoreip = 127.0.0.1/8 192.168.1.0/24 ::1
| Paramètres | Description |
|---|---|
| bantime | durée du bannissement qui s’applique à une IP une fois qu’elle a atteint le seuil maxretry |
| findtime | fenêtre de temps pendant laquelle Fail2Ban compte les tentatives de connexion échouées |
| maxretry | nombre maximal d’échecs (tentatives) qu’une IP peut faire avant d’être bannie. |
| ignoreip | liste des adresses IP (IPv4 et IPv6) ignorées plages IP ; exemples : ignoreip = 127.0.0.1/8 ou ignoreip = 192.168.1.0/24 |
| action | action par défaut : utilise nftables (ou iptables) pour bannir l’IP |
Autres paramètres
| Paramètres | Description |
|---|---|
| logrotate | utilitaire système conçu pour gérer automatiquement les fichiers journaux (logs). |
| enabled | simple booléen (true/false ou 1/0) qui active ou désactive une jail (une règle de protection pour un service donné) |
| destemail | adresse e-mail à laquelle Fail2Ban enverra les notifications ou les rapports |
Activer la prison SSH (sshd)
Maintenant que les valeurs par défaut sont définies, nous allons créer (ou surcharger) la section spécifique au service SSH (nommé sshd dans Fail2ban).
On modifie le fichier jail.local :
sudo nano /etc/fail2ban/jail.local
On cherche la partie [sshd] :
[sshd]
enabled = true
port = ssh
filter = sshd
maxretry = 3
bantime = 48h
logpath = %(sshd_log)s
Le paramètre filter = sshd indique à Fail2ban d’utiliser le fichier de filtre pré-écrit /etc/fail2ban/filter.d/sshd.conf. Ce fichier contient les expressions régulières (failregex) nécessaires pour identifier les lignes de tentatives de connexion échouées dans le fichier de journal (auth.log).
On applique les modifications :
sudo systemctl restart fail2ban
On vérifie que Fail2ban fonctionne :
sudo systemctl status fail2ban
Doit renvoyer :
● fail2ban.service - Fail2Ban Service
Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; enabled; preset: enabled)
Active: active (running) since Thu 2025-11-20 13:47:43 CET; 1s ago
Invocation: 1ff45edcd8eb4238bbaec105c3c9cf2c
Docs: man:fail2ban(1)
Main PID: 72339 (fail2ban-server)
Tasks: 7 (limit: 4596)
Memory: 14.4M (peak: 16.8M)
CPU: 1.627s
CGroup: /system.slice/fail2ban.service
├─72339 /usr/bin/python3 /usr/bin/fail2ban-server -xf start
└─72448 /usr/bin/python3 /usr/bin/fail2ban-server -xf start
nov. 20 13:47:43 sd-117585 systemd[1]: Started fail2ban.service - Fail2Ban Service.
nov. 20 13:47:43 sd-117585 fail2ban-server[72339]: Server ready
Pour vérifier l’état de la prison [sshd] :
sudo fail2ban-client status sshd
Vous devriez voir une sortie similaire à ceci, confirmant que le filtre surveille le bon journal :
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
La Prison spéciale
On va créer une prison pour bannir des adresses IP manuellement et éviter de rentrer en conflit avec d¹autres filtres.
Voici comment la mettre en place :
On va ajouter cette nouvelle section dans votre fichier de configuration local, soit /etc/fail2ban/jail.local, soit dans un nouveau fichier de la structure /etc/fail2ban/jail.d/.
On ouvre jail.local :
sudo nano /etc/fail2ban/jail.local
On ajoute à la fin du fichier :
[manual-jail]
enabled = true
logpath = /dev/null
filter =
bantime = 1y
maxretry = 1
| Paramètres | Description |
|---|---|
| enabled | on active la prison |
| logpath | pas de chemin de journal (on ne surveille rien) |
| filter | pas de filtre associé (on ne cherche pas de tentatives d’échec) |
| bantime | on va lui donner un temps de bannissement très long, 1 an |
| maxretry |
Note : en utilisant logpath = /dev/null, on indique à Fail2ban de ne lire aucun fichier pour cette prison, ce qui réduit la charge inutile.
On active la prison :
sudo systemctl restart fail2ban
On vérifie qu’elle est active :
sudo fail2ban-client status manual-jail
Vous devriez voir une sortie similaire à ceci, confirmant que la prison est active :
Status for the jail: manual-jail
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /dev/null
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
Une fois le service Fail2ban redémarré et la prison activée, on va pouvoir l’utiliser à tout moment pour bannir / dé-bannir une IP spécifique.
Exemple Fail2ban pour nginx
Fail2ban fournit déjà des prisons (jails) et filtres prêts à l’emploi pour nginx, notamment nginx-http-auth, nginx-botsearch, nginx-bad-request, nginx-forbidden et nginx-limit-req. La prison nginx-http-auth surveille par défaut le log d’erreurs Nginx, et nginx-limit-req suppose que le module ngx_http_limit_req_module est utilisé.
sudo nano /etc/fail2ban/jail.local
On y ajoute ;
[DEFAULT]
backend = systemd
banaction = nftables-multiport
bantime = 1h
findtime = 10m
maxretry = 5
bantime.increment = true
bantime.factor = 2
bantime.max = 1w
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
[sshd]
enabled = true
port = 22
logpath = %(sshd_log)s
maxretry = 3
[nginx-http-auth]
enabled = true
port = http,https
logpath = %(nginx_error_log)s
maxretry = 5
[nginx-botsearch]
enabled = true
port = http,https
logpath = %(nginx_error_log)s
maxretry = 10
[nginx-bad-request]
enabled = true
port = http,https
logpath = %(nginx_error_log)s
maxretry = 10
[nginx-forbidden]
enabled = true
port = http,https
logpath = %(nginx_error_log)s
maxretry = 10
Récidive
La prision recidive sert à re-bannir plus longtemps les IP qui reviennent régulièrement.
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
banaction = nftables-multiport
bantime = 1w
findtime = 1d
maxretry = 5
Installation automatique
Un script qui installe automatiquement nftables, fail2ban, curl, active les services, crée une base nftables.
Il crée une config Fail2ban avec sshd, nginx-http-auth, nginx-botsearch, apache-auth, recidive :
#!/usr/bin/env bash
set -euo pipefail
echo "1/7 Installation des paquets..."
apt update
apt install -y nftables fail2ban curl
echo "2/7 Activation des services..."
systemctl enable nftables
systemctl enable fail2ban
echo "3/7 Sauvegarde des configs existantes...
[ -f /etc/nftables.conf ] && cp /etc/nftables.conf /etc/nftables.conf.bak.$(date +%F-%H%M%S)
[ -f /etc/fail2ban/jail.local ] && cp /etc/fail2ban/jail.local /etc/fail2ban/jail.local.bak.$(date +%F-%H%M%S)
echo "4/7 Écriture de /etc/nftables.conf ..."
cat > /etc/nftables.conf <<'EOF'
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0;
policy drop;
iif lo accept
ct state established,related accept
# Ping
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
# SSH
tcp dport 22 accept
# Web
tcp dport { 80, 443 } accept
}
chain forward {
type filter hook forward priority 0;
policy drop;
}
chain output {
type filter hook output priority 0;
policy accept;
}
}
EOF
echo "5/7 Écriture de /etc/fail2ban/jail.local ..."
cat > /etc/fail2ban/jail.local <<'EOF'
[DEFAULT]
backend = systemd
banaction = nftables-multiport
bantime = 1h
findtime = 10m
maxretry = 5
bantime.increment = true
bantime.factor = 2
bantime.max = 1w
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
[sshd]
enabled = true
port = 22
logpath = %(sshd_log)s
maxretry = 3
[nginx-http-auth]
enabled = true
port = http,https
logpath = %(nginx_error_log)s
maxretry = 5
[nginx-botsearch]
enabled = true
port = http,https
logpath = %(nginx_error_log)s
maxretry = 10
[apache-auth]
enabled = true
port = http,https
logpath = /var/log/apache2/error.log
maxretry = 5
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
banaction = nftables-multiport
bantime = 1w
findtime = 1d
maxretry = 5
EOF
echo "6/7 Application des règles..."
nft -f /etc/nftables.conf
systemctl restart nftables
systemctl restart fail2ban
echo "7/7 Vérifications..."
echo
echo "=== nftables ==="
nft list ruleset || true
echo
echo "=== fail2ban ==="
fail2ban-client status || true
echo
echo "Installation terminée."
Commandes nftables et fail2ban
nft est l’outil officiel pour inspecter et administrer nftables.
La commande fail2ban-client est l’outil officiel pour piloter le service, et fail2ban-regex permet de tester les filtres sur des logs avant mise en production.
Règles actuelles :
sudo nft list ruleset
Afficher les jails actives :
sudo fail2ban-client status
Afficher une jail précise :
sudo fail2ban-client status nginx-http-auth
Tester un filtre :
sudo fail2ban-regex /var/log/nginx/error.log /etc/fail2ban/filter.d/nginx-http-auth.conf
Bannir une IP :
sudo fail2ban-client set sshd banip 195.24.12.52
Débannir une IP :
sudo fail2ban-client set sshd unbanip 195.2.12.52
Afficher toutes les options disponibles :
fail2ban-client -h
Status du service :
sudo fail2ban-client status
Status de la prison sshd :
sudo fail2ban-client status sshd
Vérifier les IP bannies :
sudo fail2ban-client status
Vérifier les IP bannies pour ssh :
sudo fail2ban-client status sshd
Afficher les logs :
sudo journalctl -u fail2ban
Tester regex (très utile) :
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
Protection brute force directement dans nftables :
tcp dport 22 ct state new limit rate 10/minute accept
