WAF / Caddy / Nginx / Fail2ban
Contactez-moi- Nginx
- Caddy
- FrankenPHP
- Coraza
- Fail2ban
- WAF
Cette pile couvre la protection et l’exposition d’un serveur web : un reverse proxy (Nginx ou Caddy) reçoit le trafic entrant, termine le TLS et route vers les applications ; un WAF (Web Application Firewall) filtre les requêtes malveillantes au niveau applicatif (injections, XSS…) ; Fail2ban surveille les journaux et bannit automatiquement les IP responsables de tentatives d’intrusion répétées (brute-force, scans).
Historique
Nginx est publié en 2004 par Igor Sysoev pour résoudre le problème du “C10K” (gérer des dizaines de milliers de connexions simultanées) qui limitait Apache. Caddy apparaît en 2015, porté par Matt Holt, avec une promesse différente : HTTPS automatique par défaut via Let’s Encrypt, sans configuration manuelle des certificats. Fail2ban, lancé en 2004, répond au besoin de bannir automatiquement les IP abusives détectées dans les logs (SSH, HTTP…). Le concept de WAF, formalisé par des projets comme ModSecurity (2002), ajoute une couche de filtrage applicatif au-dessus du filtrage réseau classique.
Avantages des versions récentes
- Caddy 2 (réécriture 2020) : configuration déclarative (Caddyfile), HTTPS automatique y compris en interne, support HTTP/3 natif.
- Nginx 1.25+ : support HTTP/3 (QUIC) natif, réduisant la latence sur connexions mobiles/instables.
- TLS on-demand : émission de certificats à la volée pour des domaines dynamiques, utile en multi-tenant.
- Règles WAF gérées (type OWASP Core Rule Set) régulièrement mises à jour contre les nouvelles classes d’attaques.
En production : FrankenPHP, Caddy et Coraza
En production, j’utilise FrankenPHP. C’est un serveur d’applications PHP moderne, écrit en Go et construit sur Caddy : il exécute PHP directement dans le serveur web, sans PHP-FPM ni processus séparé, et conserve tout ce que Caddy apporte (HTTPS automatique, HTTP/3, configuration déclarative en Caddyfile).
Le point d’entrée du trafic est donc un seul composant, qui sert les applications PHP et fait le reverse proxy des autres applications.
J’y ai ajouté le WAF Coraza. Coraza est un pare-feu applicatif écrit en Go, compatible avec les règles OWASP Core Rule Set : il intègre Caddy sous forme de module et inspecte chaque requête avant qu’elle n’atteigne l’application. Une requête qui déclenche une règle OWASP (injection SQL, XSS, traversée de répertoires, sonde de scanner…) est refusée avec une erreur 403.
Fail2ban : bannir les IP qui déclenchent des 403
Le WAF bloque la requête, mais pas son auteur : un scanner peut renvoyer des milliers de requêtes. Fail2ban ferme cette boucle :
- Chaque refus du WAF apparaît comme une erreur 403 dans les journaux du serveur.
- Fail2ban surveille ces journaux et repère les adresses IP qui accumulent des 403, c’est-à-dire qui enfreignent les règles OWASP.
- Il bannit l’adresse au niveau du pare-feu du système, iptables, pendant 1 heure : l’IP n’atteint plus le serveur du tout, et le ban expire seul.
Un seul point d’entrée pour toutes les applications
La même instance protège et expose l’ensemble de mes applications, pas seulement celles écrites en PHP. Les applications d’un autre langage ou d’une autre pile passent par le reverse proxy de Caddy et reçoivent la même protection :
- WAF commun : toutes les requêtes passent par les règles OWASP de Coraza avant d’atteindre l’application derrière.
- Bannissement commun : une IP qui attaque une application est bannie pour toutes les autres, puisque le ban se fait au niveau du pare-feu du serveur.
- HTTPS automatique pour chaque domaine, sans gérer les certificats application par application.
- Une seule configuration à maintenir plutôt qu’un serveur web par application.
Cette configuration est entièrement optimisée pour tenir ce rôle de point d’entrée unique.
Mon expertise
J’ai mis en production une protection complète à l’entrée du serveur :
- FrankenPHP, serveur PHP construit sur Caddy, en production ;
- WAF Coraza ajouté à Caddy, avec les règles OWASP ;
- Fail2ban, qui bannit les adresses générant des erreurs 403, c’est-à-dire celles qui enfreignent ces règles ;
- un point d’entrée unique : la même instance fait aussi le reverse proxy de mes autres applications, avec la même protection.