Use Case:
Ein Community-Mitglied wollte neben den SentinelOne Threat Alerts auch Activity Alerts per API in Wazuh integrieren – basierend auf dem offiziellen Wazuh-Blog zur SentinelOne-Integration. Die Logs wurden korrekt abgeholt und in separate JSON-Dateien geschrieben, dennoch wurden Activity Alerts weder im Dashboard angezeigt noch durch Custom Rules erkannt.
Ausgangslage
Setup
- Eigener Python-Collector (
sentinelone.py) - Zwei Logfiles:
/var/log/sentinelone_threats.json/var/log/sentinelone_activities.json
- Einbindung via:
wodle command(periodischer Script-Run)localfile-Definitionen mitlog_format=json
- Eigene Regeln:
- 100600 → Threat Logs
- 100610 → Activity Logs
Symptome
- ✅ Threat Alerts funktionieren korrekt
- ❌ Activity Alerts erscheinen nicht im Dashboard
- ❌
wazuh-logtestmatched weder Threat- noch Activity-Regeln, sondern fällt immer auf die generische JSON-Regel (id 1002, Level 2) zurück
Root Cause 1: Indexing- & Mapping-Problem im Filebeat-Pipeline
Die eigentliche Ursache lag nicht in den Regeln, sondern im Filebeat Ingest Pipeline:
- Die Activity Logs enthielten ein verschachteltes Feld
data - Dieses kollidierte mit bestehenden OpenSearch-Mappings
- Ergebnis:
👉 Logs wurden zwar verarbeitet, aber nicht korrekt indexiert
👉 Dadurch konnten sie im Dashboard nicht angezeigt werden
Lösung: Painless Script in der Filebeat Pipeline
In der Datei/usr/share/filebeat/module/wazuh/alerts/ingest/pipeline.json
wurde ein zusätzliches Script eingefügt:
{
"script": {
"description": "move data to sentinel.",
"lang": "painless",
"source": "ctx.sentinel = ctx.remove('data');",
"if": "ctx.location != null && ctx.location.contains('/var/log/sentinelone_activities.json')"
}
}
Effekt:
- Das problematische Feld
datawird entfernt - Inhalt wird sauber nach
sentinelverschoben - Mapping-Konflikt ist behoben
Danach:
filebeat setup --pipelines
systemctl restart filebeat
➡️ Activity Alerts erschienen anschließend korrekt im Dashboard
Root Cause 2: Regel-Matching zu generisch
Nach der Pipeline-Fix tauchte ein neues Problem auf:
- Die Activity-Regel (100610) matchte plötzlich auch Threat Logs
- Ursache:
<match>accountId</match>Das FeldaccountIdexistiert in beiden Logtypen
Finale Regel-Korrektur
Die Lösung war eine präzisere Match-Bedingung mit Regex-Anker:
<rule id="100610" level="3">
<decoded_as>json</decoded_as>
<match>^{"accountId":</match>
<description>SentinelOne: Activity Log - Type $(activityType)</description>
<options>no_full_log</options>
</rule>
Warum das funktioniert:
- Activity Logs beginnen mit
{"accountId": - Threat Logs haben andere JSON-Strukturen
- Der
^-Anker stellt sicher, dass nur Activity Logs matchen
Nach:
systemctl restart wazuh-manager
➡️ Saubere Trennung von Threat- und Activity-Regeln
Lessons Learned (Best Practices)
1. Nicht jedes Problem ist ein Rule-Problem
Wenn Logs:
- im File ankommen,
- aber nicht im Dashboard erscheinen,
👉 immer zuerst Filebeat & Ingest Pipelines prüfen
2. Vorsicht bei generischen <match>-Bedingungen
- Felder wie
accountId,id,typesind oft nicht eindeutig - Besser:
- Regex-Anker (
^) - Kombination mehrerer Felder
- oder strukturelle Unterschiede nutzen
- Regex-Anker (
3. wazuh-logtest ≠ Filebeat Pipeline
wazuh-logtesttestet nur Rule-Matching- Es berücksichtigt keine Filebeat-Ingest-Scripts
- Unterschiede zwischen Logtest & Dashboard sind daher möglich und erklärbar
Fazit
Die SentinelOne Activity Integration funktionierte am Ende vollständig und stabil, nachdem:
- Ein Index-Mapping-Konflikt in Filebeat behoben wurde
- Die Rule-Matching-Logik präzisiert wurde
Dieser Fall zeigt sehr gut, wie Wazuh Rules, Filebeat Pipelines und OpenSearch Mappings zusammenspielen – und warum Troubleshooting immer End-to-End gedacht werden muss.
👉 Ein echtes Community-Best-Practice-Beispiel.
https://wazuh.slack.com/archives/C0A933R8E/p1765360901708659