En bref : Fail2ban lit les fichiers journaux et bannit dans le pare-feu les adresses qui se font trop remarquer dans une fenêtre de temps. Pour Nginx et Apache, il fournit des jails prêts à l'emploi comme nginx-botsearch ou apache-noscript ; vous testez vos propres filtres avec fail2ban-regex. Les paramètres vont dans jail.local, vos propres adresses dans ignoreip, le jail recidive rattrape les récidivistes. Fail2ban n'aide pas contre des attaques ciblées isolées, mais bien contre les analyses de masse.
Quand les journaux sont pleins de scanners
Qui consulte ces jours-ci les journaux d'accès de ses serveurs web les trouve souvent remplis de requêtes vers des chemins qui n'existent pas : anciennes interfaces d'administration, fichiers de test, failles connues d'autres produits. Dans une situation comme PHP2Shell s'y ajoute la recherche ciblée de serveurs vulnérables : Cloudflare et Patchstack ont fait état de tentatives d'attaque, Unit 42 a dénombré plus de 22,6 millions d'instances exposées et potentiellement vulnérables.
Fail2ban est un outil éprouvé contre cette masse. Il lit les fichiers journaux, détecte avec des filtres les entrées suspectes et bannit l'adresse de l'expéditeur dans le pare-feu pour une durée définie. Cela soulage le serveur, réduit le bruit dans les journaux et rend plus laborieux le tâtonnement systématique depuis une même source.
Ce que Fail2ban ne sait pas faire est tout aussi important : une requête isolée qui exploite une faille n'est pas empêchée. Contre PHP2Shell, seule la mise à jour de PHP aide. Le déroulement des attaques automatisées est décrit dans Analyses de masse après un PHP non corrigé.
Fail2ban pour Nginx et Apache : les jails fournis
Un jail relie un filtre à un fichier journal et à une action de bannissement. Le jail.conf fourni contient déjà des jails pour les serveurs web. Ils sont désactivés par défaut et s'activent un à un.
| Jail | Serveur web | Détecte |
|---|---|---|
nginx-http-auth |
Nginx | connexions HTTP Basic échouées |
nginx-limit-req |
Nginx | requêtes dépassant la limite de débit de Nginx |
nginx-botsearch |
Nginx | recherche de chemins typiques inexistants |
nginx-bad-request |
Nginx | requêtes erronées |
apache-auth |
Apache | connexions échouées |
apache-badbots |
Apache | identifiants de robots malveillants connus |
apache-noscript |
Apache | appels de scripts inexistants |
apache-overflows |
Apache | requêtes trop longues |
apache-botsearch |
Apache | recherche de chemins typiques inexistants |
php-url-fopen |
les deux | certains motifs de tentatives d'inclusion d'URL |
recidive |
les deux | adresses que Fail2ban a bannies à répétition |
Les valeurs par défaut de la configuration fournie sont plutôt clémentes : bannissement de 10 minutes après 5 occurrences en 10 minutes. Pour les serveurs web soumis à beaucoup de trafic de scan, un bannissement plus long et un facteur croissant pour les récidives valent la peine.
La configuration de base dans jail.local
Le jail.conf dit lui-même qu'il ne doit pas être modifié, car les mises à jour le remplacent. Les valeurs personnelles vont dans /etc/fail2ban/jail.local. L'exemple suivant pour Nginx définit des valeurs par défaut raisonnables et active des jails adaptés :
# /etc/fail2ban/jail.local
[DEFAULT]
# Inscrire vos propres adresses fixes (remplacer l'adresse d'exemple)
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
bantime = 1h
findtime = 10m
maxretry = 5
bantime.increment = true
[nginx-http-auth]
enabled = true
[nginx-botsearch]
enabled = true
[recidive]
enabled = true
bantime = 1w
findtime = 1d
Pour Apache, vous activez plutôt par exemple apache-auth, apache-noscript et apache-botsearch. Fail2ban apporte les chemins de journaux selon la distribution ; si vos chemins diffèrent, définissez logpath dans le jail concerné. Si votre système ne lit les journaux que via le journal systemd, backend = systemd aide.
Un filtre personnalisé pour les requêtes de masse vers des fichiers PHP
Un motif typique dans la situation actuelle est le grand nombre de requêtes en peu de temps vers des fichiers PHP qui n'existent pas. Un filtre personnalisé le détecte grâce au code d'état 404. Il décrit uniquement ce qui figure dans votre propre journal :
# /etc/fail2ban/filter.d/nginx-php-404.conf
[Definition]
failregex = ^<HOST> -.*"(GET|POST|HEAD) [^"]*\.php[^"]*" 404
ignoreregex =
# Complément dans /etc/fail2ban/jail.local
[nginx-php-404]
enabled = true
port = http,https
filter = nginx-php-404
logpath = /var/log/nginx/access.log
maxretry = 20
findtime = 1m
bantime = 1h
Avant d'activer le filtre, testez-le sur le vrai journal. Vous voyez ainsi combien de lignes il touche et s'il y a des accès légitimes parmi elles :
fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-php-404.conf
sudo systemctl restart fail2ban
sudo fail2ban-client status
sudo fail2ban-client status nginx-php-404
# Débannir une adresse bannie par erreur
sudo fail2ban-client set nginx-php-404 unbanip 203.0.113.25
Choisissez le seuil avec largesse. Un robot d'exploration qui traite de vieux liens ou un service de supervision ne doit pas finir banni.
Les pièges les plus fréquents
Fail2ban s'installe vite, mais s'emploie facilement de travers. Vérifiez ces points avant l'utilisation en production :
- S'auto-bloquer : les adresses du bureau, du VPN et de la supervision doivent figurer dans
ignoreipavant que les jails ne soient actifs. - Services placés en amont : derrière un CDN ou un répartiteur de charge, Fail2ban ne voit, sans adaptation, que leurs adresses. Plus de détails dans le guide Protéger les connexions d'administration contre la force brute.
- Rotation des journaux : après le changement du fichier journal, Fail2ban doit lire le nouveau fichier. Vérifiez après la première rotation que les jails continuent de compter les occurrences.
- Interaction avec le pare-feu : Fail2ban inscrit les bannissements dans le pare-feu. Qui gère son pare-feu par un rechargement complet du jeu de règles peut supprimer ces entrées. La manière de construire le pare-feu lui-même est décrite dans Pare-feu pour serveurs web : n'ouvrir que les ports nécessaires.
- IPv6 : les attaques arrivent aussi par IPv6. Vérifiez que votre action de bannissement couvre les deux protocoles.
Analysez régulièrement les listes de bannissement. Si les bannissements se multiplient depuis certains réseaux ou sur certains chemins, c'est le signe d'une recherche ciblée et une raison d'examiner de plus près l'application concernée.
Conclusion : un outil contre la masse, pas contre tout
Fail2ban se configure vite et décharge les serveurs web d'une partie du bombardement permanent. Les jails fournis couvrent les motifs typiques, les filtres personnalisés peuvent être testés sans risque sur de vrais journaux avec fail2ban-regex, et le jail recidive fait en sorte que les sources obstinées restent plus longtemps dehors.
Il ne faut pas le surestimer. Fail2ban réagit à la répétition, pas à la première occurrence, et ne voit que ce qui figure dans les journaux. Contre une faille comme PHP2Shell, seule la mise à jour aide, et contre des attaques distribuées depuis de nombreuses adresses, Fail2ban n'aide guère. Il déploie sa valeur comme une couche parmi d'autres : aux côtés d'un pare-feu épuré, d'une configuration de serveur web durcie, d'une authentification à deux facteurs et d'une supervision qui ne se contente pas de bloquer les anomalies, mais les signale aussi.
Comment PHP SOS aide-t-il concrètement ?
- Analyser les journaux : nous examinons les motifs qui apparaissent dans vos journaux d'accès et choisissons les jails adaptés.
- Configurer et tester : nous mettons en place Fail2ban avec des filtres personnalisés, testons chaque filtre sur de vrais journaux et inscrivons vos adresses fixes en exception.
- Clarifier l'interaction : nous accordons CDN, répartiteur de charge, pare-feu et rotation des journaux de sorte que les bannissements touchent les bonnes adresses.
- Observer : dans le cadre de la supervision de sécurité, nous analysons en continu bannissements et anomalies.
Questions fréquentes
Fail2ban protège-t-il contre PHP2Shell ?
Non. Fail2ban ne réagit qu'après qu'une adresse s'est fait remarquer plusieurs fois dans les journaux. Une seule attaque réussie n'est pas empêchée. Mais Fail2ban réduit la charge due aux scanners et renchérit les tentatives répétées depuis la même source.
Pourquoi ne pas modifier jail.conf directement ?
Le fichier est remplacé lors des mises à jour de paquets, et il le dit lui-même. Les paramètres personnels vont dans un jail.local ou dans des fichiers sous jail.d. Ils y remplacent les valeurs par défaut de façon ciblée.
Qu'est-ce que le jail recidive ?
Un jail qui exploite le journal de Fail2ban lui-même. Qui est banni à répétition reçoit un bannissement nettement plus long. Dans la configuration fournie, il est d'une semaine.
Fail2ban fonctionne-t-il derrière Cloudflare ou un répartiteur de charge ?
Seulement avec une configuration supplémentaire. Sans elle, les journaux contiennent l'adresse du service placé en amont, et un bannissement toucherait tous les visiteurs. Le serveur web doit alors reprendre la vraie adresse du visiteur, et les bannissements sont de préférence posés chez le service en amont.