Jamf Protect & Wazuh Integration: JSON-Decoding, Regeln und Alerts im Dashboard korrekt konfigurieren

Einleitung (Einordnung, Relevanz für Security/SIEM/Wazuh)

Die Integration von Jamf Protect-Logs in Wazuh zur zentralen Sicherheitsanalyse stellt viele Organisationen vor Parsing-, Decoding- und Rule-Mapping-Herausforderungen. Obwohl die Logs bereits im JSON-Format vorliegen, muss Wazuh sie korrekt einlesen, decodieren und Regeln auslösen, damit sie im Wazuh-Dashboard erscheinen. Dieser Beitrag erklärt, wie Wazuh JSON-Logs aufnimmt, wie passende Regeln geschrieben und warum Alerts im Dashboard möglicherweise nicht angezeigt werden – mit klaren Schritten und Doku-Quellen.

Ausgangslage / Problemstellung (Zusammenfassung, Symptome, Umgebung)

Setup:
Ein Python-Skript schreibt Jamf Protect-Logs im JSON-Format in ein Logfile (z. B. /var/log/jamf_protect/alerts.log). Wazuh liest diese Datei via <localfile> aus ossec.conf, und die JSON-Strukturen werden erkannt.

Probleme:

  • Es ist unklar, ob zusätzliche custom decoders nötig sind, obwohl die Logs im JSON-Format vorliegen.
  • Custom Rules feuern im logtest korrekt (Alert generiert), erscheinen aber nicht im Wazuh Dashboard.
  • Unsicherheit, wie JSON-Felder im Rule-Matching korrekt angesprochen werden.

Technische Analyse (Ursachen, betroffene Komponenten, Architekturbezug, Stolpersteine)

1) JSON-Parsing in Wazuh – Decoder notwendig?

Wazuh bringt einen Standard JSON-Decoder mit, der gültige JSON-Logs automatisch verarbeitet. Solange die Logs valide JSON-Objekte darstellen und von Wazuh als solche eingelesen werden, ist kein eigener Decoder notwendig. Der JSON-Decoder in der Wazuh-Doku beschreibt genau dieses Verhalten:
👉 JSON decoder – Decoders

2) Wie Wazuh JSON-Logs liest

Wazuh liest Dateien über <localfile>-Abschnitte in /var/ossec/etc/ossec.conf. Für korrektes Logging aus Jamf Protect muss klar definiert sein:

<localfile>
  <log_format>json</log_format>
  <location>/var/log/jamf_protect/alerts.log</location>
</localfile>

Dieses Snippet sorgt dafür, dass Wazuh JSON erwartet und decodiert.

Ein häufiger Stolperstein: Wazuh liest zwar die Datei, erkennt aber durch falsche <log_format>-Angabe kein JSON, was zu falschem Decoding führt.

3) Rule-Matching der JSON-Felder

Damit eine Rule feuert, müssen die in field name="…" referenzierten Felder tatsächlich existieren und korrekt im JSON dargestellt sein. Beispiel-JSON:

{"eventType":"GPScreenshotEvent","severity":"Informational","integration_source":"jamf_protect","computer":{"hostName":"HOST"}}

In Wazuh-Rules verwendet man z. B.:

<field name="severity">Informational</field>

Ein Fehler war, wenn im Rule-Snippet ein Feld (integration_source) referenziert wird, das im JSON nicht korrekt vorhanden ist – oder anders heißt. Exakte Feldnamen und Verschachtelungen müssen übereinstimmen.

4) Warum Alert im Dashboard fehlt

Selbst wenn wazuh-logtest ein Alert-Objekt erzeugt, wird dieses nicht automatisch im Dashboard dargestellt. Gründe:

  1. Threshold-Level:
    Wazuh zeigt standardmäßig nur Alerts mit Level ≥ 3 im Dashboard an. Ein Rule-Level <level>2</level> erzeugt zwar einen Alert, aber der gilt als zu „niedrig“ und wird nicht angezeigt. Kevin Branch (Community) hat diesen Punkt bestätigt. Ändert man <level>2</level> auf <level>3</level>, erscheinen die Alerts wie erwartet.
  2. Indexierung / Mappings:
    Wenn Alerts im Log (/var/ossec/logs/alerts/alerts.json) stehen, aber nicht im Dashboard auftauchen, kann ein Mapping-Conflict in der Indexierung vorliegen – z. B. wenn ein Feld einmal als String und einmal als Integer indexiert wurde. Dann lehnt OpenSearch/Indexer die Dokumente ab und sie erscheinen nicht im Dashboard.
  3. Ingestion / Filebeat:
    Da Wazuh intern Filebeat nutzt, kann ein Indexierungsfehler auch in Filebeat-Logs auftauchen (z. B. „unable to index document …“). Kevin Branch empfiehlt die Filebeat-Logs zu prüfen:
grep filebeat /var/log/syslog /var/log/messages

Lösung / Best Practices (konkrete Schritte, Konfigurationen, Reihenfolge)

Schritt 1 — Localfile korrekt setzen

In ossec.conf:

<localfile>
    <log_format>json</log_format>
    <location>/var/log/jamf_protect/alerts.log</location>
</localfile>

Schritt 2 — Regeln wie im Beispiel strukturieren (Level ≥ 3)

Beispiel für die wichtigsten Fälle:

<group name="jamf_protect,">

  <rule id="100500" level="3">
    <decoded_as>json</decoded_as>
    <field name="integration_source">jamf_protect</field>
    <description>Jamf Protect Base Rule</description>
  </rule>

  <rule id="100501" level="3">
    <if_sid>100500</if_sid>
    <field name="severity">Informational</field>
    <description>Jamf Informational</description>
    <group>jamf_info,</group>
  </rule>

  <rule id="100502" level="5">
    <if_sid>100500</if_sid>
    <field name="severity">Low</field>
    <description>Jamf Low Severity</description>
    <group>jamf_low,</group>
  </rule>

  <rule id="100503" level="7">
    … <!-- Medium -->
  </rule>

  <rule id="100504" level="12">
    … <!-- High -->
  </rule>

</group>

Tipp: Wazuh empfiehlt, Rule IDs im Bereich 100000–120000 für eigene Regeln zu nutzen, um Konflikte mit Systemregeln zu vermeiden.

Schritt 3 — Alerts überprüfen

Direkt auf dem Manager:

grep jamf_protect /var/ossec/logs/alerts/alerts.json

Wenn hier schon keine Alerts stehen, liegt ein Parsing/Rule-Matching-Problem vor.

Schritt 4 — Falls Alerts in alerts.json stehen, aber nicht im Dashboard

  • Check Filebeat- und Indexer-Logs auf Indexierungs-Fehler.
  • Prüfe OpenSearch-Mapping für die relevanten Felder.
  • Nutze Kibana/OpenSearch Dashboards – Dev-Tools, um abgelegte Dokumente zu sehen.

Lessons Learned / Best Practices (präventive Maßnahmen, Betrieb, Skalierung)

  • Regex/Field-Name-Accuracy: JSON ist case-sensitive. Kleinste Unterschiede im Feldnamen verhindern Rule-Matches.
  • Rule‐Level bewusst setzen: Alerts erst ab Level 3 im Wazuh Dashboard sichtbar.
  • Test workflow:
    1. Wazuh-Logtest → decode + rule match
    2. Alerts.json → Alert vorhanden?
    3. Filebeat/Indexer logs → Indexierung OK?
    4. Dashboard-Visualisierung prüfen.
  • Indexierungskonflikte vermeiden: Einheitliche Feldtypen über alle Logs/Integrationen – sonst drohen abgewiesene Dokumente.

Fazit (knappe Zusammenfassung mit Mehrwert)

Für Jamf Protect-Logs im JSON-Format ist kein eigener Decoder notwendig, solange Wazuh sie als JSON einliest. Entscheidend ist eine korrekte <localfile>-Konfiguration und Rule-Definition mit passenden Feldnamen und ausreichender Schwere (level). Wenn Alerts im logtest erscheinen, aber nicht im Dashboard, liegt das häufig an zu niedrigem Rule-Level oder Indexierungs-/Mapping-Problemen. Ein systematisches Prüfen von Alerts.json, Filebeat- und Indexer-Logs führt schnell zur Lösung.

Relevante Doku-Links

👉 JSON Decoder – Wazuh Docs:
https://documentation.wazuh.com/current/user-manual/ruleset/decoders/json-decoder.html

👉 Monitoring JSON Logs mit <localfile>:
https://documentation.wazuh.com/current/user-manual/ruleset/decoders/json-decoder.html

👉 Regel-IDs und custom Rules:
https://documentation.wazuh.com/current/user-manual/ruleset/ruleset-xml/syntax.html


Mehr zu Wazuh …
https://wazuh.com/?utm_source=ambassadors&utm_medium=referral&utm_campaign=ambassadors+program

Mehr zum Wazuh Ambassador Program …
https://wazuh.com/ambassadors-program/?utm_source=ambassadors&utm_medium=referral&utm_campaign=ambassadors+program

https://wazuh.slack.com/archives/C0A933R8E/p1768203584962159