
Ce guide présente une installation et une configuration complètes de Fail2Ban pour Nginx, conçues pour :
- bloquer les véritables scanners et tentatives d’exploitation (par exemple les requêtes vers
/.env,/.git,/phpmyadmin, etc.), - éviter le blocage accidentel des administrateurs (problème fréquent lorsque le bannissement repose uniquement sur les erreurs HTTP),
- bannir les adresses IP après des activités suspectes répétées,
- utiliser une courte durée de bannissement (5 minutes) afin de réduire le risque de s’auto-bloquer.
Pourquoi bannir uniquement sur la base des erreurs HTTP peut poser problème
De nombreux guides recommandent de bannir les adresses IP uniquement selon les codes de statut HTTP (4xx/499). En pratique, cela provoque souvent des auto-blocages, car les applications modernes génèrent de nombreuses requêtes (AJAX, panneaux d’administration, reconstruction du cache), ce qui peut entraîner des erreurs HTTP lors d’une utilisation normale.
Cette configuration adopte une approche plus sûre :
- les chemins d’exploitation sont toujours considérés comme suspects,
- les erreurs HTTP ne sont comptabilisées que lorsque la requête ne contient pas d’en-tête Referer (comportement typique des scanners),
- les User-Agents malveillants connus sont pris en compte.
Étape 1 : Installer Fail2Ban
Installez Fail2Ban :
|
1 2 |
apt update apt install -y fail2ban |
Activez et démarrez le service :
|
1 2 |
systemctl enable fail2ban systemctl start fail2ban |
Vérifiez son fonctionnement :
|
1 2 |
fail2ban-client ping systemctl status fail2ban |
Étape 2 : Créer le filtre nginx-secure
Créez le fichier de filtre :
|
1 |
nano /etc/fail2ban/filter.d/nginx-secure.conf |
Collez la configuration suivante :
|
1 2 3 4 5 6 7 8 9 10 |
[Definition] failregex = ^<HOST> - .* "(?:GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH|PROPFIND|CONNECT) (?:/\.env|/wp-config\.php|/phpinfo\.php|/(?:phpmyadmin|adminer)(?:/|$)|/(?:\.git|\.svn|\.hg)(?:/|$)|/vendor/phpunit/|/cgi-bin/).*" \d{3} .* ^<HOST> - .* "(?:GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH|PROPFIND|CONNECT) [^"]*" (?:400|403|404|405|408|413|414|429|444) [^"]* "-" ".*" ^<HOST> - .* "(?:GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH|PROPFIND|CONNECT).*" \d{3} .* "(?:[^"]*)" "(?:[^"]*(?:sqlmap|nikto|masscan|zgrab|nmap|acunetix|wpscan|dirbuster|gobuster)[^"]*)" ignoreregex = |
Étape 3 : Créer le jail nginx-secure
Créez le fichier de configuration du jail :
|
1 |
nano /etc/fail2ban/jail.d/nginx-secure.conf |
Collez la configuration suivante :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[nginx-secure] enabled = true port = http,https filter = nginx-secure logpath = /var/log/nginx/access.log /var/log/nginx/access-*.log findtime = 600 maxretry = 20 bantime = 300 action = iptables-multiport[name=nginx-secure, port="http,https"] ignoreip = 127.0.0.1/8 ::1 |
Étape 4 : Redémarrer Fail2Ban
|
1 2 |
fail2ban-server -t systemctl restart fail2ban |
Étape 5 : Vérifier l’intégration avec le pare-feu
Vérifiez que la chaîne Fail2Ban existe :
|
1 2 |
iptables -S | grep f2b-nginx-secure iptables -L f2b-nginx-secure -n -v |
Test depuis une machine externe
Test du chemin d’exploitation :
|
1 2 3 |
for i in 1 2 3 4 5; do curl -I https://soban.pl/.env done |
Test de la logique des erreurs sans Referer :
|
1 2 3 |
for i in 1 2 3 4 5; do curl -sS -o /dev/null -w "%{http_code}\n" https://soban.pl/this-path-should-not-exist-$i done |
Après plusieurs requêtes suspectes, l’adresse IP sera bannie pendant 5 minutes.
Vérifier les adresses IP bannies
|
1 |
fail2ban-client status nginx-secure |
Débannir une adresse IP
Retirer un bannissement manuellement :
|
1 |
fail2ban-client set nginx-secure unbanip YOUR_IP |
Résumé
- bloque les véritables scanners et tentatives d’exploitation,
- réduit le risque d’auto-blocage des administrateurs,
- utilise un bannissement court de 5 minutes,
- compatible avec iptables-nft,
- facile à tester et à débannir.