Einleitung
Netzwerk- und Controller-Plattformen wie iMaster NCE liefern Alarmmeldungen häufig in proprietären Formaten, die sich nicht „out of the box“ in ein SIEM-Regelwerk integrieren lassen. Wazuh ist hier stark, weil sich Logquellen über Custom Decoders schnell strukturieren lassen – erst damit werden aus Textzeilen belastbare Felder für Korrelation, Dashboards und Alarmregeln. In diesem Beitrag zeige ich anhand realer iMaster-Alarmzeilen, wie man Logingest, Decoder und Regeln so aufsetzt, dass Wazuh daraus konsistente Alerts erzeugt – ohne Parser-Fragilität und ohne unnötige Datenflut.
Ausgangslage / Problemstellung
Die iMaster-Logs werden via localfile eingesammelt und enthalten Alarmmeldungen im Stil:
- Prefix mit ISO-Zeitstempel, Quelle, Prozess (
iMaster NCE[ALARM] AC-004) - Block mit
alarm resource="..." probableCause="..." perceivedSeverity=... eventType=... resourceURI=... - Key-Value-Felder wie
alarmId,alarmName,alarmType,occurTime,locationInfo - Ein großer Freitextblock
additionInfo="... (Details) ..." type="Alarm"
Ziel:
- Wazuh soll Felder wie
probableCause,perceivedSeverity,eventType,alarmName,alarmId,locationInfozuverlässig extrahieren. - Darauf basierend sollen Alerts nach Schweregrad und Typ sauber geroutet werden (z. B. WARNING vs. CRITICAL, EQUIPMENT vs. ENVIRONMENTAL).
- Decoder sollen robust gegen kleine Formatvariationen sein (Quotes, Leerzeichen, zusätzliche Inhalte).
Technische Analyse
Wazuh verarbeitet Logs in mehreren Stufen: Predecoder → Decoder → Rules. Entscheidend für Custom Logs ist:
- Decoder müssen stabil den „Anker“ im Log finden (Prematch) und danach gezielt Werte extrahieren.
- Mehrere Decoder mit identischem Namen sind problematisch: Der letzte gewinnt oder es kommt zu unerwartetem Verhalten. In der Praxis sollten Decoder eindeutig benannt sein.
- Regex wie
(\.+)sind in diesem Kontext riskant:.matcht „beliebiges Zeichen“,\.+bedeutet „ein oder mehr Punkte“. Das ist selten das gewünschte Verhalten. Für „beliebiger Text bis zum nächsten Anführungszeichen“ ist meist([^"]+)die richtige Wahl. - Große Felder wie
additionInfoenthalten oft Anführungszeichen, Sonderzeichen und Klammern. Hier lohnt es sich, zunächst nur den gesamten Block sicher zu erfassen und optional später in einem zweiten Schritt zu verfeinern.
Lösung / Best Practices
Im Folgenden ein praxistaugliches Setup: (A) Log-Ingest prüfen, (B) Decoder sauber definieren, (C) Regeln auf die extrahierten Felder bauen, (D) Test- und Betriebscheckliste.
A) Log-Ingest verifizieren (localfile / archives.json nur temporär)
Wenn die Logs über localfile kommen, ist der wichtigste Debug-Schritt sicherzustellen, dass Wazuh wirklich den Rohtext so sieht, wie er im File steht. Falls unklar, kann man auf dem Manager temporär archives.json aktivieren (<logall_json>yes</logall_json>), um das Feld full_log zu sehen. Danach unbedingt wieder deaktivieren, weil das sehr schnell Storage frisst.
B) Robuste Custom Decoder für iMaster NCE
Lege eine eigene Datei an, z. B.:
/var/ossec/etc/decoders/local_imaster_decoders.xml
Empfohlener Decoder (robust, eindeutige Namen, feldorientiert):
<decoder name="imaster_nce_parent">
<!-- Anker: "iMaster NCE[ALARM]" irgendwo in der Zeile -->
<prematch>iMaster\s+NCE\[ALARM\]</prematch>
</decoder>
<!-- Alarm resource UUID -->
<decoder name="imaster_alarm_resource">
<parent>imaster_nce_parent</parent>
<regex>alarm\s+resource="([^"]+)"</regex>
<order>imaster.alarm_resource</order>
</decoder>
<!-- probableCause -->
<decoder name="imaster_probable_cause">
<parent>imaster_nce_parent</parent>
<regex>probableCause="([^"]+)"</regex>
<order>imaster.probable_cause</order>
</decoder>
<!-- perceivedSeverity -->
<decoder name="imaster_perceived_severity">
<parent>imaster_nce_parent</parent>
<regex>perceivedSeverity=([A-Z]+)</regex>
<order>imaster.perceived_severity</order>
</decoder>
<!-- eventType -->
<decoder name="imaster_event_type">
<parent>imaster_nce_parent</parent>
<regex>eventType="([^"]+)"</regex>
<order>imaster.event_type</order>
</decoder>
<!-- resourceURI -->
<decoder name="imaster_resource_uri">
<parent>imaster_nce_parent</parent>
<regex>resourceURI="([^"]+)"</regex>
<order>imaster.resource_uri</order>
</decoder>
<!-- alarmId -->
<decoder name="imaster_alarm_id">
<parent>imaster_nce_parent</parent>
<regex>alarmId="(\d+)"</regex>
<order>imaster.alarm_id</order>
</decoder>
<!-- alarmName -->
<decoder name="imaster_alarm_name">
<parent>imaster_nce_parent</parent>
<regex>alarmName="([^"]+)"</regex>
<order>imaster.alarm_name</order>
</decoder>
<!-- alarmType -->
<decoder name="imaster_alarm_type">
<parent>imaster_nce_parent</parent>
<regex>alarmType="(\d+)"</regex>
<order>imaster.alarm_type</order>
</decoder>
<!-- occurTime -->
<decoder name="imaster_occur_time">
<parent>imaster_nce_parent</parent>
<regex>occurTime="([^"]+)"</regex>
<order>imaster.occur_time</order>
</decoder>
<!-- locationInfo -->
<decoder name="imaster_location_info">
<parent>imaster_nce_parent</parent>
<regex>locationInfo="([^"]+)"</regex>
<order>imaster.location_info</order>
</decoder>
<!-- additionInfo + type -->
<decoder name="imaster_addition_info">
<parent>imaster_nce_parent</parent>
<regex>additionInfo="([^"]+)"\s+type="([^"]+)"</regex>
<order>imaster.addition_info,imaster.record_type</order>
</decoder>
Permissions setzen:
chmod 660 /var/ossec/etc/decoders/local_imaster_decoders.xml
chown wazuh:wazuh /var/ossec/etc/decoders/local_imaster_decoders.xml
Warum diese Variante stabiler ist:
([^"]+)verhindert „Greedy“-Probleme und stoppt zuverlässig am nächsten Quote- jeder Decoder hat einen eindeutigen Namen (kein Überschreiben)
- Felder werden in einen eigenen Namespace (
imaster.*) geschrieben – das reduziert Kollisionen mit Standarddecodern
C) Regeln für Alerts nach Severity und Typ
Sobald die Felder extrahiert sind, lassen sich Regeln sehr sauber aufbauen. Beispiel: WARNING in EQUIPMENT als mittlere Priorität, ENVIRONMENTAL als Info, bestimmte Ursachen wie IP-Konflikt höher priorisieren.
In /var/ossec/etc/rules/local_rules.xml:
<group name="imaster,nce,">
<!-- Basisregel: alles was imaster_nce_parent matched -->
<rule id="110000" level="3">
<decoded_as>imaster_nce_parent</decoded_as>
<description>iMaster NCE Alarm (roh)</description>
<group>network,imaster,</group>
</rule>
<!-- WARNING -->
<rule id="110010" level="6">
<if_sid>110000</if_sid>
<field name="imaster.perceived_severity">WARNING</field>
<description>iMaster NCE Alarm: WARNING - $(imaster.alarm_name)</description>
<group>network,imaster,warning,</group>
</rule>
<!-- ENVIRONMENTAL WARNING etwas niedriger -->
<rule id="110011" level="5">
<if_sid>110010</if_sid>
<field name="imaster.event_type">ENVIRONMENTAL</field>
<description>iMaster NCE Environmental Warning: $(imaster.alarm_name)</description>
<group>network,imaster,environmental,</group>
</rule>
<!-- ARP IP conflict als höher priorisiertes Finding -->
<rule id="110020" level="10">
<if_sid>110010</if_sid>
<match>ARP detects IP conflict</match>
<description>iMaster NCE: ARP IP conflict detected (ESN: $(imaster.location_info))</description>
<group>network,imaster,ip_conflict,</group>
</rule>
</group>
Hinweis: Je nach Wazuh-Version und Decoder-Ergebnis kann decoded_as alternativ über program_name/prematch-Ketten laufen. Entscheidend ist: Erst sicherstellen, dass die Felder im Alert-JSON ankommen, dann die Rule-Logik finalisieren.
D) Testen ohne Ratespiel: wazuh-logtest
Nach dem Einspielen:
- Decoder und Rules testen mit
wazuh-logtest(Manager). - Eine Beispielzeile einfügen und prüfen, ob Felder (
imaster.*) extrahiert werden und welche Rule-ID triggert. - Erst danach
wazuh-managerneu starten und Live-Logs beobachten.
Lessons Learned / Best Practices
- Decoder zuerst stabil machen, dann Regeln: Wenn Feldextraktion wackelt, wird jedes Rule-Tuning zur Dauerbaustelle.
- Eindeutige Decodernamen verwenden: Gleichnamige Decoder sind eine Fehlerquelle.
- Regex defensiv schreiben: Für quoted values ist
([^"]+)meist die beste Basis. - archives.json nur kurzfristig aktivieren: Debug ja, Dauerbetrieb nein.
- Namespace für Felder nutzen:
imaster.*verhindert Kollisionen und macht Dashboards/Queries sauberer. - Severity-Mapping dokumentieren: Was bedeutet WARNING in iMaster? In vielen Umgebungen muss das in SIEM-Prioritäten übersetzt werden (z. B. WARNING = Level 6, CRITICAL = Level 12).
Fazit
Mit wenigen, aber sauber konstruierten Custom Decoders lassen sich iMaster NCE Alarme in Wazuh zuverlässig strukturieren. Der Schlüssel ist eine robuste Prematch-Strategie, defensives Regex-Design und ein klares Feld-Namespace. Darauf aufbauend entstehen wartbare Regeln, die nach Severity, EventType und Cause priorisieren – und aus „Textspam“ echte, auswertbare Security- und Operations-Signale machen.
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/p1770539022754399