Wazuh-Anbindung der WAF (Coraza) Debian: Unterschied zwischen den Versionen
(Die Seite wurde neu angelegt: „ =Wazuh-Anbindung der WAF (Coraza)= Die '''WAF''' (HAProxy + Coraza-SPOA) liefert die Abwehr-Telemetrie an das SIEM: welcher Angriff wurde von welcher Regel ge…“) |
|||
| Zeile 1: | Zeile 1: | ||
| − | |||
=Wazuh-Anbindung der WAF (Coraza)= | =Wazuh-Anbindung der WAF (Coraza)= | ||
Die '''WAF''' (HAProxy + Coraza-SPOA) liefert die Abwehr-Telemetrie an das SIEM: welcher Angriff wurde von welcher Regel geblockt. Das ergänzt die VulnSite-Sicht — dort sieht Wazuh den Angriffsversuch im Apache-Log, hier sieht es die '''Abwehr davor'''. | Die '''WAF''' (HAProxy + Coraza-SPOA) liefert die Abwehr-Telemetrie an das SIEM: welcher Angriff wurde von welcher Regel geblockt. Das ergänzt die VulnSite-Sicht — dort sieht Wazuh den Angriffsversuch im Apache-Log, hier sieht es die '''Abwehr davor'''. | ||
| Zeile 33: | Zeile 32: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| − | ==== | + | ==== Audit-Log in Coraza aktivieren ==== |
| − | + | Die Grundinstallation setzt nur ''SecRuleEngine On''. Coraza blockt damit zwar, protokolliert die Treffer aber nirgends — es existiert weder Logdatei noch Verzeichnis. Ohne Audit-Log hat der Agent nichts zu lesen. | |
| − | ;In ''/etc/coraza-spoa/ | + | |
| − | < | + | '''Wichtig:''' Die ''SecAudit''-Direktiven sind SecRules-Anweisungen, keine YAML-Optionen. Sie gehören in den ''directives''-Block der Anwendung und '''hinter''' die Includes, da ''@coraza.conf-recommended'' eigene Audit-Voreinstellungen mitbringt. |
| − | SecAuditLogFormat JSON | + | |
| − | </ | + | ;Zielverzeichnis anlegen |
| + | <syntaxhighlight lang="bash"> | ||
| + | mkdir -p /var/log/coraza | ||
| + | </syntaxhighlight> | ||
| + | ;In ''/etc/coraza-spoa/config.yaml'' den ''directives''-Block ergänzen | ||
| + | <syntaxhighlight lang="yaml"> | ||
| + | directives: | | ||
| + | Include @coraza.conf-recommended | ||
| + | Include /etc/coraza-spoa/crs-setup.conf | ||
| + | Include /etc/coraza-spoa/coreruleset/rules/*.conf | ||
| + | SecRuleEngine On | ||
| + | SecAuditEngine On | ||
| + | SecAuditLogParts ABIJDEFHZ | ||
| + | SecAuditLogType Serial | ||
| + | SecAuditLogFormat JSON | ||
| + | SecAuditLog /var/log/coraza/audit.log | ||
| + | </syntaxhighlight> | ||
| + | ;Bedeutung der Zeilen | ||
| + | * ''SecAuditEngine On'' — jede Transaktion wird protokolliert. Für den Kursbetrieb bewusst so gewählt: bei ''RelevantOnly'' hängt es davon ab, welchen Status Coraza sieht, und den 403 erzeugt HAProxy selbst | ||
| + | * ''SecAuditLogType Serial'' — eine gemeinsame Logdatei. Ohne diese Zeile legt Coraza pro Transaktion eine eigene Datei in einem Verzeichnisbaum an, und der Agent findet nichts | ||
| + | * ''SecAuditLogFormat JSON'' — statt des nativen ModSecurity-Formats (Multiline mit Trennern wie ''--aaCuCNaqNi-A--''), das Wazuh nicht parsen kann | ||
;Daemon neu starten | ;Daemon neu starten | ||
| − | + | <syntaxhighlight lang="bash"> | |
| − | ; | + | systemctl restart coraza-spoa |
| − | + | systemctl status coraza-spoa --no-pager | |
| + | </syntaxhighlight> | ||
| + | ;Angriff absetzen und die letzte Zeile prüfen — muss mit { beginnen | ||
| + | <syntaxhighlight lang="bash"> | ||
| + | curl -ik "https://waf.it2XX.xinmen.de/?id=1' OR '1'='1" | ||
| + | tail -1 /var/log/coraza/audit.log | jq . | ||
| + | </syntaxhighlight> | ||
| + | Im JSON stehen ''transaction.client_ip'', ''transaction.request.uri'' und ''transaction.is_interrupted'' — genau die Felder, auf die die Regel weiter unten zugreift. Die auslösende CRS-Regel (z.B. 942100, libinjection) steckt als Fließtext in ''messages[].error_message''. | ||
==== Audit-Log anbinden ==== | ==== Audit-Log anbinden ==== | ||
;In ''/var/ossec/etc/ossec.conf'' auf der WAF | ;In ''/var/ossec/etc/ossec.conf'' auf der WAF | ||
| − | < | + | <syntaxhighlight lang="xml"> |
<localfile> | <localfile> | ||
<log_format>json</log_format> | <log_format>json</log_format> | ||
<location>/var/log/coraza/audit.log</location> | <location>/var/log/coraza/audit.log</location> | ||
</localfile> | </localfile> | ||
| − | </ | + | </syntaxhighlight> |
| + | ;Syntax prüfen, bevor neu gestartet wird | ||
| + | * /var/ossec/bin/wazuh-logcollector -t | ||
==== Leserechte für den Agent ==== | ==== Leserechte für den Agent ==== | ||
| − | Der '' | + | Der Logcollector läuft als ''root'', Rechte sind daher selten die Ursache. Die folgenden Schritte sind eine Kontrolle für den Fall, dass das Audit-Log gefüllt wird, im SIEM aber nichts ankommt. |
;Zugriff testen | ;Zugriff testen | ||
* sudo -u wazuh cat /var/log/coraza/audit.log > /dev/null | * sudo -u wazuh cat /var/log/coraza/audit.log > /dev/null | ||
| − | ; | + | ;Nur bei "Permission denied" |
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
| − | |||
setfacl -m u:wazuh:rx /var/log/coraza/ | setfacl -m u:wazuh:rx /var/log/coraza/ | ||
setfacl -m u:wazuh:r /var/log/coraza/audit.log | setfacl -m u:wazuh:r /var/log/coraza/audit.log | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| + | |||
=== Neustarten des Wazuh Agents === | === Neustarten des Wazuh Agents === | ||
*systemctl restart wazuh-agent.service | *systemctl restart wazuh-agent.service | ||
| + | ;Kontrolle, dass die Datei überwacht wird | ||
| + | * grep "audit.log" /var/ossec/logs/ossec.log | ||
| + | Der Logcollector liest nur Zeilen, die '''nach''' dem Öffnen der Datei dazukommen. Angriffe von vorher tauchen nicht mehr auf. | ||
==== Decoder und Regel (auf dem Wazuh-Manager) ==== | ==== Decoder und Regel (auf dem Wazuh-Manager) ==== | ||
| Zeile 70: | Zeile 101: | ||
;Decoder in ''/var/ossec/etc/decoders/local-coraza_decoders.xml'' | ;Decoder in ''/var/ossec/etc/decoders/local-coraza_decoders.xml'' | ||
| − | < | + | <syntaxhighlight lang="xml"> |
<decoder name="coraza-audit"> | <decoder name="coraza-audit"> | ||
<prematch>^{"transaction":</prematch> | <prematch>^{"transaction":</prematch> | ||
<plugin_decoder>JSON_Decoder</plugin_decoder> | <plugin_decoder>JSON_Decoder</plugin_decoder> | ||
</decoder> | </decoder> | ||
| − | </ | + | </syntaxhighlight> |
;Regel in ''/var/ossec/etc/rules/local_rules.xml'' ergänzen | ;Regel in ''/var/ossec/etc/rules/local_rules.xml'' ergänzen | ||
| − | < | + | <syntaxhighlight lang="xml"> |
<group name="coraza,waf,"> | <group name="coraza,waf,"> | ||
<rule id="100100" level="0"> | <rule id="100100" level="0"> | ||
| Zeile 91: | Zeile 122: | ||
</rule> | </rule> | ||
</group> | </group> | ||
| − | </ | + | </syntaxhighlight> |
| + | ;Regel-IDs auf Dopplung prüfen | ||
| + | Sind 100100/100101 bereits vergeben, startet ''wazuh-manager'' nicht mehr und meldet ''Duplicated rule ID'' im ossec.log. | ||
| + | * grep -rn 'rule id="1001' /var/ossec/etc/rules/ | ||
;Eigentümer und Rechte setzen | ;Eigentümer und Rechte setzen | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
| Zeile 106: | Zeile 140: | ||
;Angriff von der Kali gegen die WAF | ;Angriff von der Kali gegen die WAF | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
| − | curl " | + | curl -k "https://waf.it2XX.xinmen.de/?id=1'+OR+'1'='1" |
</syntaxhighlight> | </syntaxhighlight> | ||
;Im Dashboard | ;Im Dashboard | ||
* Öffne ''Threat Hunting'', Filter ''rule.id:100101'' | * Öffne ''Threat Hunting'', Filter ''rule.id:100101'' | ||
* Der Alert "Coraza WAF: Angriff geblockt" muss erscheinen | * Der Alert "Coraza WAF: Angriff geblockt" muss erscheinen | ||
| + | |||
| + | ==== Fehlersuche ==== | ||
| + | Die Kette von unten nach oben prüfen, in dieser Reihenfolge. | ||
| + | ;1. Blockt Coraza überhaupt? | ||
| + | <syntaxhighlight lang="bash"> | ||
| + | curl -k -o /dev/null -w "%{http_code}\n" "https://waf.it2XX.xinmen.de/?id=1'+OR+'1'='1" | ||
| + | </syntaxhighlight> | ||
| + | Kommt 200 statt 403, ist die Rule-Engine das Problem, nicht das SIEM. | ||
| + | ;2. Schreibt Coraza ins Audit-Log? | ||
| + | * tail -f /var/log/coraza/audit.log — dann den curl absetzen | ||
| + | ;3. Liest der Agent die Datei? | ||
| + | * grep "Analyzing file" /var/ossec/logs/ossec.log | ||
| + | ;4. Erreichen die Zeilen den Manager? Dort ''logall_json'' aktivieren | ||
| + | <syntaxhighlight lang="xml"> | ||
| + | <global> | ||
| + | <logall_json>yes</logall_json> | ||
| + | </global> | ||
| + | </syntaxhighlight> | ||
| + | * tail -f /var/ossec/logs/archives/archives.json | jq -c 'select(.agent.name=="waf")' | ||
| + | * Nach der Übung wieder auf ''no'' — Archives werden nicht rotiert | ||
| + | ;5. Steht die Verbindung? | ||
| + | * Auf dem Manager: /var/ossec/bin/agent_control -l | ||
| + | * Auf der WAF: grep -E "Connected to the server|Unable to connect" /var/ossec/logs/ossec.log | ||
[[Kategorie:WAZUH]] | [[Kategorie:WAZUH]] | ||
[[Kategorie:Coraza]] | [[Kategorie:Coraza]] | ||
Aktuelle Version vom 9. September 2026, 09:49 Uhr
Wazuh-Anbindung der WAF (Coraza)
Die WAF (HAProxy + Coraza-SPOA) liefert die Abwehr-Telemetrie an das SIEM: welcher Angriff wurde von welcher Regel geblockt. Das ergänzt die VulnSite-Sicht — dort sieht Wazuh den Angriffsversuch im Apache-Log, hier sieht es die Abwehr davor.
Hinweis: Wazuhs eingebaute ModSecurity-Regeln greifen nur auf das Apache-error.log klassischer ModSecurity. Coraza-SPOA schreibt ein eigenes Audit-Log und läuft nicht über Apache — daher binden wir das Coraza-JSON-Audit-Log ein und ergänzen einen eigenen Decoder samt Regel auf dem Manager.
Repository einrichten
- GPG-Schlüssel importieren
curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/wazuh.gpg --import
chmod 644 /usr/share/keyrings/wazuh.gpg
- Repository hinzufügen
echo "deb [signed-by=/usr/share/keyrings/wazuh.gpg] https://packages.wazuh.com/4.x/apt/ stable main" > /etc/apt/sources.list.d/wazuh.list
apt update
Agent installieren
- Agent mit Manager-Adresse und Namen installieren
WAZUH_MANAGER="wazuh.dkbi.com" WAZUH_AGENT_NAME="waf" apt install -y wazuh-agent
- Dienst aktivieren und starten
systemctl daemon-reload
systemctl enable --now wazuh-agent
- Repository deaktivieren
sed -i "s/^deb /#deb /" /etc/apt/sources.list.d/wazuh.list
apt update
Audit-Log in Coraza aktivieren
Die Grundinstallation setzt nur SecRuleEngine On. Coraza blockt damit zwar, protokolliert die Treffer aber nirgends — es existiert weder Logdatei noch Verzeichnis. Ohne Audit-Log hat der Agent nichts zu lesen.
Wichtig: Die SecAudit-Direktiven sind SecRules-Anweisungen, keine YAML-Optionen. Sie gehören in den directives-Block der Anwendung und hinter die Includes, da @coraza.conf-recommended eigene Audit-Voreinstellungen mitbringt.
- Zielverzeichnis anlegen
mkdir -p /var/log/coraza
- In /etc/coraza-spoa/config.yaml den directives-Block ergänzen
directives: |
Include @coraza.conf-recommended
Include /etc/coraza-spoa/crs-setup.conf
Include /etc/coraza-spoa/coreruleset/rules/*.conf
SecRuleEngine On
SecAuditEngine On
SecAuditLogParts ABIJDEFHZ
SecAuditLogType Serial
SecAuditLogFormat JSON
SecAuditLog /var/log/coraza/audit.log
- Bedeutung der Zeilen
- SecAuditEngine On — jede Transaktion wird protokolliert. Für den Kursbetrieb bewusst so gewählt: bei RelevantOnly hängt es davon ab, welchen Status Coraza sieht, und den 403 erzeugt HAProxy selbst
- SecAuditLogType Serial — eine gemeinsame Logdatei. Ohne diese Zeile legt Coraza pro Transaktion eine eigene Datei in einem Verzeichnisbaum an, und der Agent findet nichts
- SecAuditLogFormat JSON — statt des nativen ModSecurity-Formats (Multiline mit Trennern wie --aaCuCNaqNi-A--), das Wazuh nicht parsen kann
- Daemon neu starten
systemctl restart coraza-spoa
systemctl status coraza-spoa --no-pager
- Angriff absetzen und die letzte Zeile prüfen — muss mit { beginnen
curl -ik "https://waf.it2XX.xinmen.de/?id=1' OR '1'='1"
tail -1 /var/log/coraza/audit.log | jq .
Im JSON stehen transaction.client_ip, transaction.request.uri und transaction.is_interrupted — genau die Felder, auf die die Regel weiter unten zugreift. Die auslösende CRS-Regel (z.B. 942100, libinjection) steckt als Fließtext in messages[].error_message.
Audit-Log anbinden
- In /var/ossec/etc/ossec.conf auf der WAF
<localfile>
<log_format>json</log_format>
<location>/var/log/coraza/audit.log</location>
</localfile>
- Syntax prüfen, bevor neu gestartet wird
- /var/ossec/bin/wazuh-logcollector -t
Leserechte für den Agent
Der Logcollector läuft als root, Rechte sind daher selten die Ursache. Die folgenden Schritte sind eine Kontrolle für den Fall, dass das Audit-Log gefüllt wird, im SIEM aber nichts ankommt.
- Zugriff testen
- sudo -u wazuh cat /var/log/coraza/audit.log > /dev/null
- Nur bei "Permission denied"
setfacl -m u:wazuh:rx /var/log/coraza/
setfacl -m u:wazuh:r /var/log/coraza/audit.log
Neustarten des Wazuh Agents
- systemctl restart wazuh-agent.service
- Kontrolle, dass die Datei überwacht wird
- grep "audit.log" /var/ossec/logs/ossec.log
Der Logcollector liest nur Zeilen, die nach dem Öffnen der Datei dazukommen. Angriffe von vorher tauchen nicht mehr auf.
Decoder und Regel (auf dem Wazuh-Manager)
Coraza-JSON wird vom generischen JSON-Decoder zerlegt, aber von keiner eingebauten Regel klassifiziert. Beides ergänzen.
- Decoder in /var/ossec/etc/decoders/local-coraza_decoders.xml
<decoder name="coraza-audit">
<prematch>^{"transaction":</prematch>
<plugin_decoder>JSON_Decoder</plugin_decoder>
</decoder>
- Regel in /var/ossec/etc/rules/local_rules.xml ergänzen
<group name="coraza,waf,">
<rule id="100100" level="0">
<decoded_as>json</decoded_as>
<field name="transaction.client_ip">\.+</field>
<description>Coraza WAF Audit-Log.</description>
</rule>
<rule id="100101" level="10">
<if_sid>100100</if_sid>
<field name="transaction.is_interrupted">true</field>
<description>Coraza WAF: Angriff geblockt auf $(transaction.request.uri) von $(transaction.client_ip).</description>
<group>attack,web,</group>
</rule>
</group>
- Regel-IDs auf Dopplung prüfen
Sind 100100/100101 bereits vergeben, startet wazuh-manager nicht mehr und meldet Duplicated rule ID im ossec.log.
- grep -rn 'rule id="1001' /var/ossec/etc/rules/
- Eigentümer und Rechte setzen
chown wazuh:wazuh /var/ossec/etc/decoders/local-coraza_decoders.xml /var/ossec/etc/rules/local_rules.xml
chmod 660 /var/ossec/etc/decoders/local-coraza_decoders.xml /var/ossec/etc/rules/local_rules.xml
- Vor dem Neustart mit logtest prüfen — eine echte JSON-Audit-Zeile reinpasten
- /var/ossec/bin/wazuh-logtest
Erwartete Ausgabe: transaction.is_interrupted: 'true in Phase 2 und Rule id: '100101 in Phase 3.
- Erst dann Manager neu starten
- systemctl restart wazuh-manager
Kontrolle
- Angriff von der Kali gegen die WAF
curl -k "https://waf.it2XX.xinmen.de/?id=1'+OR+'1'='1"
- Im Dashboard
- Öffne Threat Hunting, Filter rule.id:100101
- Der Alert "Coraza WAF: Angriff geblockt" muss erscheinen
Fehlersuche
Die Kette von unten nach oben prüfen, in dieser Reihenfolge.
- 1. Blockt Coraza überhaupt?
curl -k -o /dev/null -w "%{http_code}\n" "https://waf.it2XX.xinmen.de/?id=1'+OR+'1'='1"
Kommt 200 statt 403, ist die Rule-Engine das Problem, nicht das SIEM.
- 2. Schreibt Coraza ins Audit-Log?
- tail -f /var/log/coraza/audit.log — dann den curl absetzen
- 3. Liest der Agent die Datei?
- grep "Analyzing file" /var/ossec/logs/ossec.log
- 4. Erreichen die Zeilen den Manager? Dort logall_json aktivieren
<global>
<logall_json>yes</logall_json>
</global>
- tail -f /var/ossec/logs/archives/archives.json | jq -c 'select(.agent.name=="waf")'
- Nach der Übung wieder auf no — Archives werden nicht rotiert
- 5. Steht die Verbindung?
- Auf dem Manager: /var/ossec/bin/agent_control -l
- Auf der WAF: grep -E "Connected to the server|Unable to connect" /var/ossec/logs/ossec.log