7 ModSecurity
romain edited this page 2026-09-11 13:32:27 +00:00

Si vous avez choisi la version WAF de Nginx

Dans le dossier qui permet le mappage des fichiers de configuration dans (/nginx/conf.d) créer un fichier mod-security.conf avec le contenu suivant :

# Chargement des regles
modsecurity_rules_file /etc/nginx/modsec/main.conf;

# Desactivation global
modsecurity off;

Au niveau des virtualhosts pour activer le WAF :

server {
...

  modsecurity on;
  modsecurity_rules '
    # Passer ce VHost en mode détection uniquement (pas de blocage)
    SecRuleEngine DetectionOnly
    SecAuditLogParts ABIJDEFHZ

    # Activer le journal d audit pour ce VHost
    SecAuditEngine RelevantOnly
    #SecAuditLogRelevantStatus "^(?:5|(?:4(?!04)))"
    # EXCLUSION DES 429 : Logue les 5xx et 4xx SAUF 404 ET SAUF 429
    SecAuditLogRelevantStatus "^(?:5|(?:4(?!04|29)))"

    # Emplacement du fichier de log spécifique
    SecAuditLog /var/log/nginx/www.domain.tld.waf.log
    SecAuditLogType Serial
    SecAuditLogFormat JSON
  ';
    
...
}

Gérer les exceptions, créer un fichier REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf que l'on va mapper dans le conteneur Nginx

services:
  nginx:
     ...
    volumes:
      - ./ms-rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf:/etc/nginx/modsec/coreruleset/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf

Exemple d'exclusion globale :

# ==================================================================
# EXCLUSION 1 : Nextcloud WebDAV
# ==================================================================
SecAction "id:1000000,phase:1,nolog,pass,setvar:'tx.allowed_methods=GET HEAD POST OPTIONS PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK REPORT DELETE PUT'"

# ==================================================================
# EXCLUSION 2
# ==================================================================
# Fix SQLi 942550 sur la recherche JSON
SecRuleUpdateTargetById 942550 "!ARGS:json.query.Url"
SecRuleUpdateTargetById 942550 "!ARGS:json.searchQuery.Url"
SecRuleUpdateTargetById 942550 "!REQUEST_COOKIES:/^ErmesSearch_/"

# Fix Content-Type 920420 pour le back-office /pro/
SecRule REQUEST_URI "@beginsWith /my-folder/" \
    "id:1000002,\
    phase:1,\
    pass,\
    nolog,\
    ctl:ruleRemoveById=920420"

Exemple d'exclusion en spécifiant les hôtes :

# ==================================================================
# 1. EXCLUSIONS Nextcloud
# ==================================================================
SecRule REQUEST_HEADERS:Host "@streq nextcloud.domain.tld" \
    "id:1000001,\
    phase:1,\
    pass,\
    nolog,\
    setvar:'tx.allowed_methods=GET HEAD POST OPTIONS PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK REPORT DELETE PUT'"

# ==================================================================
# 2. EXCLUSIONS subdom.domaine.tld
# ==================================================================
# Fix SQLi 942550
SecRule REQUEST_HEADERS:Host "@streq subdom.domaine.tld" \
    "id:1000002,\
    phase:1,\
    pass,\
    nolog,\
    ctl:ruleRemoveTargetById=942550;ARGS:json.query.Url,\
    ctl:ruleRemoveTargetById=942550;ARGS:json.searchQuery.Url,\
    ctl:ruleRemoveTargetById=942550;REQUEST_COOKIES:/^ErmesSearch_/"

# Fix Content-Type 920420
SecRule REQUEST_HEADERS:Host "@streq subdom.domaine.tld" \
    "id:1000003,\
    phase:1,\
    chain,\
    pass,\
    nolog"
    SecRule REQUEST_URI "@beginsWith /my-folder/" \
        "ctl:ruleRemoveById=920420"

Seul solution pour avoir un fichier par vhost :

  1. pas de configuration globale
  2. Déclarer dans chaque vhost le chargement de modsecurity :
modsecurity on;
  modsecurity_rules_file /etc/nginx/modsec/main.conf;
  modsecurity_rules '
      # Passer ce VHost en mode détection uniquement (pas de blocage)
      SecRuleEngine DetectionOnly

      # Activer le journal d audit pour ce VHost
      SecAuditEngine RelevantOnly
      #SecAuditLogRelevantStatus "^(?:5|(?:4(?!04)))"
      # EXCLUSION DES 429 : Logue les 5xx et 4xx SAUF 404 ET SAUF 429
      SecAuditLogRelevantStatus "^(?:5|(?:4(?!04|29)))"

      # Emplacement du fichier de log spécifique
      SecAuditLog /var/log/nginx/domain.waf.log
      SecAuditLogType Serial
      SecAuditLogFormat JSON
  ';