Les applications web sont constamment ciblées par des attaques automatisées. Un WAF (Web Application Firewall) comme ModSecurity filtre les requêtes HTTP malveillantes avant qu'elles n'atteignent votre application. Cet article vous guide dans le déploiement de ModSecurity avec l'OWASP Core Rule Set.
Plan
- Qu'est-ce qu'un WAF et ModSecurity ?
- Installation sur Nginx et Apache
- Configuration de l'OWASP Core Rule Set
- Tuning et réduction des faux positifs
- Monitoring et alerting
- Conclusion
Qu'est-ce qu'un WAF et ModSecurity ?
Un WAF (Web Application Firewall) inspecte le trafic HTTP/HTTPS pour bloquer les attaques applicatives :
- Injections SQL
- Cross-Site Scripting (XSS)
- Path traversal
- Remote File Inclusion (RFI)
- Command injection
- CSRF
ModSecurity est un WAF open source intégrable à Nginx et Apache. Il utilise des règles pour détecter et bloquer les patterns d'attaque.
OWASP Core Rule Set (CRS) est un ensemble de règles communautaires couvrant les Top 10 OWASP et plus de 200 vecteurs d'attaque.
Installation sur Nginx
1. Installer les dépendances
# Debian/Ubuntu
apt update
apt install -y git build-essential libpcre3-dev libssl-dev zlib1g-dev \
libxml2-dev libgeoip-dev liblmdb-dev libyajl-dev
# RHEL/Rocky
dnf install -y git gcc make pcre-devel openssl-devel zlib-devel \
libxml2-devel GeoIP-devel lmdb-devel yajl-devel
2. Compiler ModSecurity v3
cd /opt
git clone --depth 1 -b v3/master https://github.com/SpiderLabs/ModSecurity
cd ModSecurity
git submodule init
git submodule update
./build.sh
./configure
make -j$(nproc)
make install
3. Installer le connecteur Nginx
cd /opt
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx
nginx -V # Noter le chemin des sources Nginx
# Télécharger les sources Nginx correspondantes
NGINX_VERSION=$(nginx -v 2>&1 | grep -oP 'nginx/\K[\d.]+')
wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz
tar -xzf nginx-${NGINX_VERSION}.tar.gz
cd nginx-${NGINX_VERSION}
# Recompiler Nginx avec ModSecurity
./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
make modules
cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/
4. Activer ModSecurity dans Nginx
# /etc/nginx/nginx.conf
load_module modules/ngx_http_modsecurity_module.so;
http {
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;
# Reste de la config...
}
Installation sur Apache
# Debian/Ubuntu
apt install -y libapache2-mod-security2
# RHEL/Rocky
dnf install -y mod_security
# Activer le module
a2enmod security2
systemctl restart apache2
Configuration Apache :
# /etc/apache2/mods-enabled/security2.conf
<IfModule security2_module>
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess On
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
Include /etc/modsecurity/modsecurity.conf
Include /etc/modsecurity/crs/crs-setup.conf
Include /etc/modsecurity/crs/rules/*.conf
</IfModule>
Configuration de l'OWASP Core Rule Set
1. Télécharger le CRS
cd /opt
git clone https://github.com/coreruleset/coreruleset.git
cd coreruleset
git checkout v4.0/main
# Copier vers /etc
cp -r /opt/coreruleset /etc/modsecurity/crs
cd /etc/modsecurity/crs
mv crs-setup.conf.example crs-setup.conf
2. Configuration de base ModSecurity
# /etc/nginx/modsec/main.conf (ou /etc/modsecurity/modsecurity.conf pour Apache)
SecRuleEngine On
SecRequestBodyAccess On
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
SecRequestBodyLimitAction Reject
SecPcreMatchLimit 100000
SecPcreMatchLimitRecursion 100000
SecResponseBodyAccess On
SecResponseBodyMimeType text/plain text/html text/xml application/json
SecResponseBodyLimit 524288
SecResponseBodyLimitAction ProcessPartial
SecDebugLog /var/log/modsec_debug.log
SecDebugLogLevel 0
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
SecAuditLogParts ABIJDEFHZ
SecAuditLogType Serial
SecAuditLog /var/log/modsec_audit.log
SecUploadDir /tmp
SecTmpDir /tmp
SecDataDir /tmp
SecArgumentSeparator &
# Charger les règles CRS
Include /etc/modsecurity/crs/crs-setup.conf
Include /etc/modsecurity/crs/rules/*.conf
3. Configuration du niveau de paranoia
Le Paranoia Level contrôle la sévérité des règles (1 à 4) :
- PL1 : Règles de base, peu de faux positifs
- PL2 : Protection renforcée, risque de faux positifs modéré
- PL3 : Protection maximale, beaucoup de faux positifs
- PL4 : Ultra-paranoïaque, nombreux faux positifs
# /etc/modsecurity/crs/crs-setup.conf
SecAction \
"id:900000,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.paranoia_level=2"
Tuning et réduction des faux positifs
1. Mode DetectionOnly pour test
Commencez en mode détection sans bloquer :
# /etc/nginx/modsec/main.conf
SecRuleEngine DetectionOnly
Surveillez les logs pendant quelques jours :
tail -f /var/log/modsec_audit.log
2. Désactiver des règles spécifiques
# /etc/modsecurity/crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
# Désactiver la règle 920100 pour un vhost spécifique
SecRule REQUEST_HEADERS:Host "@streq example.com" \
"id:10001,phase:1,pass,nolog,ctl:ruleRemoveById=920100"
# Désactiver pour un path spécifique
SecRule REQUEST_URI "@beginsWith /api/upload" \
"id:10002,phase:1,pass,nolog,ctl:ruleRemoveById=921110"
3. Whitelist d'IP
# Whitelist IP pour admin
SecRule REMOTE_ADDR "@ipMatch 192.168.1.100" \
"id:10003,phase:1,pass,nolog,ctl:ruleEngine=Off"
4. Exceptions pour applications connues
Le CRS fournit des exclusions pré-configurées :
# /etc/modsecurity/crs/crs-setup.conf
# WordPress
SecAction \
"id:900130,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.crs_exclusions_wordpress=1"
# Drupal
SecAction \
"id:900140,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.crs_exclusions_drupal=1"
Monitoring et alerting
1. Analyser les logs d'audit
# Parser les logs ModSecurity
grep -oP '(?<=id ")[^"]*' /var/log/modsec_audit.log | sort | uniq -c | sort -rn
# Lister les règles déclenchées
awk '/msg/ {print}' /var/log/modsec_audit.log | grep -oP 'id "\K[^"]+' | sort | uniq -c
2. Intégration avec ELK
Installer Filebeat pour envoyer les logs vers Elasticsearch :
# /etc/filebeat/filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/modsec_audit.log
fields:
type: modsecurity
multiline:
pattern: '^--[a-f0-9]{8}-A--'
negate: true
match: after
output.elasticsearch:
hosts: ['localhost:9200']
index: 'modsecurity-%{+yyyy.MM.dd}'
3. Alerting sur attaques
# Script de monitoring
#!/bin/bash
# /usr/local/bin/modsec-alert.sh
THRESHOLD=10
ATTACKS=$(grep -c "ModSecurity: Warning" /var/log/modsec_audit.log)
if [ $ATTACKS -gt $THRESHOLD ]; then
echo "⚠️ $ATTACKS attaques détectées" | mail -s "ModSecurity Alert" admin@example.com
fi
# Réinitialiser le log
> /var/log/modsec_audit.log
Cron toutes les heures :
0 * * * * /usr/local/bin/modsec-alert.sh
Conclusion
ModSecurity avec l'OWASP CRS protège efficacement vos applications web contre les attaques courantes. Le tuning initial est essentiel pour réduire les faux positifs. Commencez en mode DetectionOnly, analysez les logs pendant quelques jours, puis basculez en mode On après avoir ajusté les exclusions.
Complétez ModSecurity avec CrowdSec pour une protection collaborative, ou Suricata pour la détection réseau avancée.
Points clés :
- Démarrez avec Paranoia Level 1 ou 2
- Mode DetectionOnly pendant 1-2 semaines minimum
- Utilisez les exclusions pré-configurées pour CMS connus
- Monitorez les logs d'audit régulièrement
- Whitelistez les IPs d'administration


