Sécurité
Web
WAF

Mettre en place un WAF avec ModSecurity et OWASP Core Rule Set

15 janvier 2026

5 min de lecture

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
Besoin d'aide sur ce sujet ?

Notre équipe d'experts est là pour vous accompagner dans vos projets d'infrastructure et d'infogérance.

Contactez-nous

Articles similaires