chore: fix wazuh modsecurity decoder + noise rules
- Réécriture modsecurity_decoder.xml pour le format JSON audit libmodsecurity3 (Docker JSON log, log_format:json) Décoders séparés : blocked (403), rule, pass - Nouveau local_modsecurity_rules.xml : alertes niveaux 6/10/12 pour règles déclenchées, blocages 403 et scan répété - local_ssh_pam_noise.xml : rule 100001 → 100010 (évite conflit avec le placeholder de local_rules.xml) - Fix mln-uber ossec.conf : gestion-waf log filename .log.json → -json.log - docker-compose.yml + wazuh.indexer.yml : upgrade 4.14.4 → 4.14.5 + compatibility.override_main_response_version: true Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -34,7 +34,7 @@ services:
|
|||||||
|
|
||||||
# ─── Wazuh Manager ────────────────────────────────────────
|
# ─── Wazuh Manager ────────────────────────────────────────
|
||||||
wazuh.manager:
|
wazuh.manager:
|
||||||
image: wazuh/wazuh-manager:4.14.4
|
image: wazuh/wazuh-manager:4.14.5
|
||||||
hostname: wazuh.manager
|
hostname: wazuh.manager
|
||||||
container_name: wazuh_manager
|
container_name: wazuh_manager
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -81,7 +81,7 @@ services:
|
|||||||
|
|
||||||
# ─── Wazuh Indexer (OpenSearch) ───────────────────────────
|
# ─── Wazuh Indexer (OpenSearch) ───────────────────────────
|
||||||
wazuh.indexer:
|
wazuh.indexer:
|
||||||
image: wazuh/wazuh-indexer:4.14.4
|
image: wazuh/wazuh-indexer:4.14.5
|
||||||
hostname: wazuh.indexer
|
hostname: wazuh.indexer
|
||||||
container_name: wazuh_indexer
|
container_name: wazuh_indexer
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -109,7 +109,7 @@ services:
|
|||||||
|
|
||||||
# ─── Wazuh Dashboard ──────────────────────────────────────
|
# ─── Wazuh Dashboard ──────────────────────────────────────
|
||||||
wazuh.dashboard:
|
wazuh.dashboard:
|
||||||
image: wazuh/wazuh-dashboard:4.14.4
|
image: wazuh/wazuh-dashboard:4.14.5
|
||||||
hostname: wazuh.dashboard
|
hostname: wazuh.dashboard
|
||||||
container_name: wazuh_dashboard
|
container_name: wazuh_dashboard
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
network.host: "0.0.0.0"
|
network.host: "0.0.0.0"
|
||||||
node.name: "wazuh.indexer"
|
node.name: "wazuh.indexer"
|
||||||
cluster.initial_master_nodes:
|
|
||||||
- "wazuh.indexer"
|
|
||||||
cluster.name: "wazuh-cluster"
|
cluster.name: "wazuh-cluster"
|
||||||
|
|
||||||
|
# Compatibilité Filebeat 7.x (libbeat) avec OpenSearch 2.x
|
||||||
|
# Filebeat envoie _type dans les requêtes bulk — OpenSearch 2.x le rejette
|
||||||
|
# sans ce flag.
|
||||||
|
compatibility.override_main_response_version: true
|
||||||
|
|
||||||
path.data: /var/lib/wazuh-indexer
|
path.data: /var/lib/wazuh-indexer
|
||||||
path.logs: /var/log/wazuh-indexer
|
path.logs: /var/log/wazuh-indexer
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,35 @@
|
|||||||
<!-- ═══════════════════════════════════════════════════════════════
|
<!-- ═══════════════════════════════════════════════════════════════
|
||||||
Decoders ModSecurity (nginx error.log)
|
Decoders ModSecurity — JSON Audit Log (libmodsecurity3)
|
||||||
Format attendu :
|
Format : {"transaction":{"client_ip":"...","request":{"uri":"..."},
|
||||||
[client IP:PORT] ModSecurity: Access denied with code 403
|
"response":{"http_code":N},"messages":[{"details":{"ruleId":"N"}}]}}
|
||||||
(phase 2). Message [id "XXXXX"] [msg "..."] [uri "..."]
|
Collecté via log_format:json sur les fichiers Docker container log
|
||||||
[client IP:PORT] ModSecurity: Warning. ... [id "XXXXX"]
|
(Wazuh extrait le champ "log" du wrapper Docker JSON avant décodage)
|
||||||
[msg "..."] [uri "..."]
|
|
||||||
═══════════════════════════════════════════════════════════════ -->
|
═══════════════════════════════════════════════════════════════ -->
|
||||||
|
|
||||||
<!-- Decoder parent : identifie toute ligne ModSecurity -->
|
<!-- Parent : toute transaction ModSecurity JSON -->
|
||||||
<decoder name="modsecurity">
|
<decoder name="docker-waf-modsec">
|
||||||
<prematch>ModSecurity: </prematch>
|
<prematch>{"transaction":{</prematch>
|
||||||
</decoder>
|
</decoder>
|
||||||
|
|
||||||
<!-- Decoder enfant : Access denied (requête bloquée) -->
|
<!-- Accès bloqué (http_code exactement 403) avec règle déclenchée.
|
||||||
<decoder name="modsecurity-block">
|
Listé en premier — priorité sur docker-waf-modsec-rule. -->
|
||||||
<parent>modsecurity</parent>
|
<decoder name="docker-waf-modsec-blocked">
|
||||||
<prematch>ModSecurity: Access denied</prematch>
|
<parent>docker-waf-modsec</parent>
|
||||||
<regex>\[client (\d+\.\d+\.\d+\.\d+):\p+\] ModSecurity: Access denied with code (\d+) \(phase \d+\)\.\s*(\S[^[]*?)\s*\[id "(\d+)"\][^\[]*\[msg "([^"]+)"\][^\[]*\[uri "([^"]+)"\]</regex>
|
<regex>"client_ip":"(\d+\.\d+\.\d+\.\d+)".+"uri":"([^"]+)".+"http_code":403.+"ruleId":"(\d+)"</regex>
|
||||||
<order>srcip,status,extra_data,id,extra_data2,url</order>
|
<order>srcip,url,id</order>
|
||||||
</decoder>
|
</decoder>
|
||||||
|
|
||||||
<!-- Decoder enfant : Warning (règle matchée sans blocage) -->
|
<!-- Règle déclenchée sans blocage (warning / anomaly scoring).
|
||||||
<decoder name="modsecurity-warning">
|
Capte aussi les non-403 avec ruleId. -->
|
||||||
<parent>modsecurity</parent>
|
<decoder name="docker-waf-modsec-rule">
|
||||||
<prematch>ModSecurity: Warning</prematch>
|
<parent>docker-waf-modsec</parent>
|
||||||
<regex>\[client (\d+\.\d+\.\d+\.\d+):\p+\] ModSecurity: Warning\.[^\[]*\[id "(\d+)"\][^\[]*\[msg "([^"]+)"\][^\[]*\[uri "([^"]+)"\]</regex>
|
<regex>"client_ip":"(\d+\.\d+\.\d+\.\d+)".+"uri":"([^"]+)".+"ruleId":"(\d+)"</regex>
|
||||||
<order>srcip,id,extra_data,url</order>
|
<order>srcip,url,id</order>
|
||||||
|
</decoder>
|
||||||
|
|
||||||
|
<!-- Trafic passant sans règle matchée (fallback) -->
|
||||||
|
<decoder name="docker-waf-modsec-pass">
|
||||||
|
<parent>docker-waf-modsec</parent>
|
||||||
|
<regex>"client_ip":"(\d+\.\d+\.\d+\.\d+)".+"uri":"([^"]+)"</regex>
|
||||||
|
<order>srcip,url</order>
|
||||||
</decoder>
|
</decoder>
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<!-- ═══════════════════════════════════════════════════════════════
|
||||||
|
Règles ModSecurity — WAF container (gestion-waf)
|
||||||
|
Source : logs JSON audit libmodsecurity3 via docker-waf-modsec*
|
||||||
|
srcip = client_ip, url = uri, id = ruleId
|
||||||
|
═══════════════════════════════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<group name="web,modsecurity,">
|
||||||
|
|
||||||
|
<!-- Trafic passant sans règle déclenchée — supprimé (niveau 0) -->
|
||||||
|
<rule id="100100" level="0">
|
||||||
|
<decoded_as>docker-waf-modsec-pass</decoded_as>
|
||||||
|
<description>ModSecurity: trafic légitime (supprimé).</description>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- Règle WAF déclenchée sans blocage (warning / anomaly scoring) -->
|
||||||
|
<rule id="100101" level="6">
|
||||||
|
<decoded_as>docker-waf-modsec-rule</decoded_as>
|
||||||
|
<description>ModSecurity: règle $(id) — $(srcip) → $(url)</description>
|
||||||
|
<group>web,modsecurity,attack,</group>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- Accès bloqué (HTTP 403) -->
|
||||||
|
<rule id="100102" level="10">
|
||||||
|
<decoded_as>docker-waf-modsec-blocked</decoded_as>
|
||||||
|
<description>ModSecurity: accès bloqué (403) — $(srcip) → $(url) [règle $(id)]</description>
|
||||||
|
<group>web,modsecurity,attack,blocked,</group>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- Blocages répétés depuis la même IP → scan ou attaque -->
|
||||||
|
<rule id="100103" level="12" frequency="5" timeframe="60">
|
||||||
|
<if_matched_sid>100102</if_matched_sid>
|
||||||
|
<same_source_ip />
|
||||||
|
<description>ModSecurity: blocages répétés depuis $(srcip) — scan ou attaque</description>
|
||||||
|
<group>web,modsecurity,attack,blocked,</group>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
</group>
|
||||||
@@ -7,6 +7,37 @@
|
|||||||
détection de brute-force (5710, 5716, 5720, 5760, 5763…)
|
détection de brute-force (5710, 5716, 5720, 5760, 5763…)
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
<!-- ─── DPKG ───────────────────────────────────────────────────────────── -->
|
||||||
|
<group name="syslog,dpkg,">
|
||||||
|
<rule id="2901" level="0" overwrite="yes">
|
||||||
|
<if_sid>2900</if_sid>
|
||||||
|
<description>Dpkg: supprimé.</description>
|
||||||
|
</rule>
|
||||||
|
<rule id="2902" level="0" overwrite="yes">
|
||||||
|
<if_sid>2900</if_sid>
|
||||||
|
<description>Dpkg: supprimé.</description>
|
||||||
|
</rule>
|
||||||
|
<rule id="2903" level="0" overwrite="yes">
|
||||||
|
<if_sid>2900</if_sid>
|
||||||
|
<description>Dpkg: supprimé.</description>
|
||||||
|
</rule>
|
||||||
|
<rule id="2904" level="0" overwrite="yes">
|
||||||
|
<if_sid>2900</if_sid>
|
||||||
|
<description>Dpkg: supprimé.</description>
|
||||||
|
</rule>
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<!-- ─── IP ADMIN (90.50.148.138) ─────────────────────────────────────── -->
|
||||||
|
<!-- Auth success supprimé pour l'IP admin : pas de valeur sécurité,
|
||||||
|
les échecs restent visibles si l'IP était usurpée. -->
|
||||||
|
<group name="syslog,sshd,">
|
||||||
|
<rule id="100010" level="0">
|
||||||
|
<if_sid>5715</if_sid>
|
||||||
|
<srcip>90.50.148.138</srcip>
|
||||||
|
<description>sshd: auth success IP admin — supprimé.</description>
|
||||||
|
</rule>
|
||||||
|
</group>
|
||||||
|
|
||||||
<!-- ─── PAM ──────────────────────────────────────────────────────────── -->
|
<!-- ─── PAM ──────────────────────────────────────────────────────────── -->
|
||||||
<group name="pam,syslog,">
|
<group name="pam,syslog,">
|
||||||
|
|
||||||
@@ -74,3 +105,30 @@
|
|||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
|
<!-- ─── IOC Suricata/Windows — parents exclus (0475, 0580, 0840) ──────────
|
||||||
|
Ces règles dans 0999-malicious-ioc-rules.xml ont des if_sid qui
|
||||||
|
pointent vers des fichiers exclus. Sans overwrite, analysisd log des
|
||||||
|
warnings (7617)/(7619) au démarrage. On les remplace par des règles
|
||||||
|
level 0 pour silence les warnings sans affecter la détection IOC SSH. -->
|
||||||
|
<group name="ids,">
|
||||||
|
<rule id="99917" level="0" overwrite="yes">
|
||||||
|
<match>.</match>
|
||||||
|
<description>Suricata: malicious domain — non applicable (pas d'agent Suricata).</description>
|
||||||
|
</rule>
|
||||||
|
<rule id="99918" level="0" overwrite="yes">
|
||||||
|
<match>.</match>
|
||||||
|
<description>Suricata: malicious domain DNS — non applicable.</description>
|
||||||
|
</rule>
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<group name="windows,windows_security,">
|
||||||
|
<rule id="99919" level="0" overwrite="yes">
|
||||||
|
<match>.</match>
|
||||||
|
<description>Windows: failed logon malicious IP — non applicable (pas d'agent Windows).</description>
|
||||||
|
</rule>
|
||||||
|
<rule id="99920" level="0" overwrite="yes">
|
||||||
|
<match>.</match>
|
||||||
|
<description>Windows: successful logon malicious IP — non applicable.</description>
|
||||||
|
</rule>
|
||||||
|
</group>
|
||||||
|
|||||||
Reference in New Issue
Block a user