Cisco-IOS-Syslog mit Millisekunden in Wazuh korrekt dekodieren

Einleitung

Cisco-IOS-Geräte können Syslog-Zeitstempel in unterschiedlichen Varianten ausgeben: mit oder ohne Jahr, Zeitzone und Millisekunden. Für Wazuh ist diese Formatvielfalt relevant, weil bereits eine kleine Abweichung im Zeitstempel dazu führen kann, dass der übergeordnete Cisco-IOS-Decoder nicht greift.

Das Ereignis wird in diesem Fall zwar vom Wazuh Manager empfangen, aber nicht als Cisco-IOS-Meldung strukturiert. Felder wie Facility, Severity und Mnemonic fehlen anschließend für Regeln, Korrelationen und Dashboards. Dadurch entsteht ein potenzieller Monitoring-Blindspot, obwohl das Rohereignis technisch im System angekommen ist.

Ausgangslage / Problemstellung

Betroffen war ein Cisco-IOS-Syslog im folgenden Format:

host.domain.com : Jul 21 2026 15:09:33.812 CEST: %SYS-SW1-5-CONFIG_I: Configured from console by username on vty0 (10.10.10.1)

Der Wazuh-Regeltest zeigte für dieses Ereignis:

**Phase 1: Completed pre-decoding.
    full event: 'host.domain.com : Jul 21 2026 15:09:33.812 CEST: %SYS-SW1-5-CONFIG_I: Configured from console by username on vty0 (10.10.10.1)'

**Phase 2: Completed decoding.
    No decoder matched.

Wurden ausschließlich die Millisekunden entfernt, funktionierte die Dekodierung:

host.domain.com : Jul 21 2026 15:09:33 CEST: %SYS-SW1-5-CONFIG_I: Configured from console by username on vty0 (10.10.10.1)

Das Ergebnis enthielt anschließend die erwarteten Cisco-Felder:

name: 'cisco-ios'
cisco.facility: 'SYS-SW1'
cisco.mnemonic: 'CONFIG_I'
cisco.severity: '5'

Die eigentliche Cisco-Meldung war somit gültig. Ausschlaggebend war die Kombination aus:

  • zweistelligem Kalendertag,
  • vierstelligem Jahr,
  • Millisekunden,
  • Zeitzone.

Technische Analyse

Wazuh verarbeitet eingehende Logs in mehreren Stufen. Zunächst versucht das Pre-Decoding, typische Syslog-Bestandteile wie Zeitstempel, Hostname und Programmname zu erkennen. Danach wählen die Decoder anhand von program_name, prematch und regulären Ausdrücken einen passenden Decoder aus. Erst anschließend werden die dekodierten Felder gegen Regeln geprüft.

Beim betroffenen Ereignis erkannte das Pre-Decoding wegen des vorangestellten Formats host.domain.com : keinen klassischen Syslog-Header. Der relevante Cisco-IOS-Parent-Decoder musste deshalb innerhalb des vollständigen Ereignisses nach dem Cisco-Zeitstempel und dem anschließenden Prozentzeichen suchen.

Die untersuchte Version von 0065-cisco-ios_decoders.xml enthält dafür mehrere prematch-Alternativen. Sie berücksichtigen unter anderem Cisco-Zeitstempel mit Jahr, Zeitzone und Millisekunden. Die Datei dokumentiert ausdrücklich, dass diese Bestandteile abhängig von der Gerätekonfiguration optional vorkommen können.

Für die Kombination aus Jahr, Millisekunden und Zeitzone war folgende Abschlussalternative vorhanden:

<prematch>\w+\s+\d\p*\s\d+\s\d+:\d+:\d+.\d+\s+\w+:\s+%</prematch>

Das Problem liegt im Abschnitt für den Kalendertag:

\d\p*

In Wazuhs OSRegex steht \d für genau eine Ziffer. \p* akzeptiert danach beliebig viele Satz- und Sonderzeichen, aber keine weitere Ziffer. Ein einstelliger Tag wie Jul 9 kann deshalb passen, während ein zweistelliger Tag wie Jul 21 an der zweiten Ziffer scheitert.

Ohne Millisekunden wird eine andere, korrekt definierte Alternative verwendet. Deshalb funktioniert das ansonsten identische Ereignis sofort, sobald .812 entfernt wird.

Ein weiterer wichtiger Punkt ist die Verarbeitung mehrfacher prematch-Elemente: Wazuh behandelt sie nicht als vollständig voneinander unabhängige XML-Bedingungen, sondern verkettet ihre Inhalte zu einem gemeinsamen Ausdruck. Die vorhandenen Alternativen enden daher bis auf die letzte Zeile mit |. Wird eine zusätzliche Zeile an der falschen Position eingefügt, kann ein ungültiger oder nicht mehr erreichbarer Gesamtausdruck entstehen.

Auch die Punktsyntax ist bei OSRegex ungewöhnlich. Ein nicht maskierter Punkt steht dort für einen literalen Punkt. \. bedeutet dagegen „beliebiges Zeichen“. Der Ausdruck zwischen Sekunden und Millisekunden muss deshalb in diesem Decoder tatsächlich als .\d+ geschrieben werden und darf nicht unreflektiert nach PCRE-Konvention in \.\d+ geändert werden.

Lösung / Best Practices

Die mit Wazuh ausgelieferte Datei unter /var/ossec/ruleset/decoders/ sollte nicht direkt verändert werden. Änderungen in diesem Verzeichnis können bei einem Upgrade überschrieben werden. Der von Wazuh dokumentierte Weg besteht darin, die vollständige Decoder-Datei nach /var/ossec/etc/decoders/ zu kopieren und anschließend die Originaldatei über decoder_exclude auszuschließen.

1. Konfiguration sichern

sudo cp -a /var/ossec/etc/ossec.conf \
  /var/ossec/etc/ossec.conf.bak.$(date +%F-%H%M%S)

2. Cisco-IOS-Decoder in das benutzerdefinierte Verzeichnis kopieren

sudo cp /var/ossec/ruleset/decoders/0065-cisco-ios_decoders.xml \
  /var/ossec/etc/decoders/custom-cisco-ios_decoders.xml

Anschließend werden Eigentümer und Berechtigungen gesetzt:

sudo chown wazuh:wazuh \
  /var/ossec/etc/decoders/custom-cisco-ios_decoders.xml

sudo chmod 660 \
  /var/ossec/etc/decoders/custom-cisco-ios_decoders.xml

Die vollständige Datei muss kopiert werden, weil sie neben dem Parent-Decoder auch die zugehörigen Cisco-IOS-Child-Decoder enthält. Würde ausschließlich ein neuer Parent mit demselben Namen angelegt, könnten Decoder-Reihenfolge, Mehrfachdefinitionen und die vorhandenen Child-Decoder zu unerwartetem Verhalten führen.

3. Fehlerhafte prematch-Alternative korrigieren

Die benutzerdefinierte Datei wird mit einem Editor geöffnet:

sudoedit /var/ossec/etc/decoders/custom-cisco-ios_decoders.xml

Innerhalb des cisco-ios-Blocks für Datums- und Zeitformate wird die fehlerhafte Abschlussalternative gesucht:

<prematch>\w+\s+\d\p*\s\d+\s\d+:\d+:\d+.\d+\s+\w+:\s+%</prematch>

Sie wird durch folgende Variante ersetzt:

<prematch>\p*\w+\s+\d+\s+\d+\s+\d+:\d+:\d+.\d+\s+\w+:\s+%</prematch>

Der Ausdruck verarbeitet nun beispielsweise:

Jul 21 2026 15:09:33.812 CEST: %

Die Bestandteile sind:

\p*       optionale Cisco-Zeitmarkierung wie * oder .
\w+       Monat
\s+       Leerzeichen
\d+       ein- oder zweistelliger Kalendertag
\s+
\d+       Jahr
\s+
\d+:\d+:\d+
.         literaler Punkt in OSRegex
\d+       Millisekunden
\s+
\w+       Zeitzone
:\s+%     Übergang zur Cisco-Meldungskennung

Das Ersetzen der bisherigen Abschlussalternative ist sicherer, als eine weitere prematch-Zeile unkontrolliert am Ende einzufügen. Bei einer zusätzlichen Alternative müsste sichergestellt werden, dass zwischen ihr und der vorherigen Alternative ein | vorhanden ist.

Nicht empfehlenswert wäre eine Änderung auf:

\d+\.\d+

Bei Wazuh OSRegex würde \. nicht ausschließlich den Punkt zwischen Sekunden und Millisekunden abbilden, sondern ein beliebiges Zeichen akzeptieren.

4. Originaldecoder in ossec.conf ausschließen

In der bestehenden Datei /var/ossec/etc/ossec.conf wird der vorhandene <ruleset>-Block ergänzt. Es darf dafür kein zweiter paralleler <ruleset>-Block angelegt werden.

Die relevante Konfiguration sollte sinngemäß folgendermaßen aussehen:

<ruleset>
  <decoder_dir>ruleset/decoders</decoder_dir>
  <rule_dir>ruleset/rules</rule_dir>

  <decoder_dir>etc/decoders</decoder_dir>
  <rule_dir>etc/rules</rule_dir>

  <decoder_exclude>ruleset/decoders/0065-cisco-ios_decoders.xml</decoder_exclude>
</ruleset>

In Standardinstallationen ist etc/decoders üblicherweise bereits eingetragen. Der bestehende Block sollte deshalb geprüft und nur um den fehlenden decoder_exclude-Eintrag ergänzt werden.

decoder_exclude verhindert, dass der originale und der angepasste Cisco-IOS-Decoder gleichzeitig geladen werden. Wazuh lädt stattdessen die vollständige Kopie aus /var/ossec/etc/decoders/. Die verfügbaren Regeln und Child-Decoder bleiben dadurch erhalten.

5. Konfiguration vor dem Neustart validieren

Die globale Ruleset- und Decoder-Konfiguration lässt sich mit wazuh-analysisd prüfen:

sudo /var/ossec/bin/wazuh-analysisd -t

Der Parameter -t führt einen Konfigurationstest durch und sollte vor jedem Manager-Neustart verwendet werden.

6. Beide Zeitstempelformate mit wazuh-logtest testen

sudo /var/ossec/bin/wazuh-logtest

Danach werden sowohl das Format mit als auch das Format ohne Millisekunden eingefügt:

host.domain.com : Jul 21 2026 15:09:33.812 CEST: %SYS-SW1-5-CONFIG_I: Configured from console by username on vty0 (10.10.10.1)

host.domain.com : Jul 21 2026 15:09:33 CEST: %SYS-SW1-5-CONFIG_I: Configured from console by username on vty0 (10.10.10.1)

Für beide Ereignisse muss Phase 2 mindestens folgende Felder liefern:

name: 'cisco-ios'
cisco.facility: 'SYS-SW1'
cisco.severity: '5'
cisco.mnemonic: 'CONFIG_I'

wazuh-logtest lädt Decoder und Regeln in einer eigenen Testsitzung. Gespeicherte Decoder-Änderungen können deshalb bereits vor dem Manager-Neustart geprüft werden. Für die produktive Ereignisverarbeitung ist anschließend weiterhin ein Neustart des Managers erforderlich.

Die in Phase 3 angezeigte Regel-ID und das Alert-Level können je nach Wazuh-Version und installierten eigenen Regeln abweichen. Entscheidend für diesen Test ist zunächst, dass der Decoder greift und die Cisco-Felder extrahiert werden.

7. Wazuh Manager neu starten

sudo systemctl restart wazuh-manager

Anschließend sollte der Dienststatus kontrolliert werden:

sudo systemctl status wazuh-manager --no-pager

Lessons Learned / Best Practices

Decoder-Tests müssen reale Zeitstempelvarianten enthalten

Ein einzelnes erfolgreich getestetes Cisco-Syslogformat reicht nicht aus. Für Netzwerkgeräte sollte mindestens eine Testmatrix aus folgenden Varianten gepflegt werden:

  • einstelliger und zweistelliger Kalendertag,
  • mit und ohne Jahr,
  • mit und ohne Millisekunden,
  • mit und ohne Zeitzone,
  • mit * oder . als Cisco-Zeitstatus,
  • mit Sequenznummer oder Origin-ID,
  • mit und ohne vorgeschalteten Syslog-Relay-Hostname.

Gerade die Kombination mehrerer optionaler Bestandteile deckt Fehler auf, die bei isolierten Tests nicht sichtbar werden.

Nicht nur Phase 3 kontrollieren

Bei Decoderproblemen ist Phase 2 des Regeltests entscheidend. Wird dort No decoder matched angezeigt, kann eine nachgelagerte Regel das Ereignis nicht über strukturierte Cisco-Felder auswerten.

Ein vorhandenes Rohlog ist daher nicht automatisch gleichbedeutend mit funktionierender Security Detection.

Level 0 ist kein produktiver Alarm

Im ursprünglichen Test wurde nach erfolgreicher Dekodierung eine generische Cisco-IOS-Regel mit Level 0 erreicht. Das bedeutet, dass das Ereignis zwar klassifiziert wurde, daraus aber nicht zwingend ein sichtbarer Alarm entsteht.

Für sicherheitsrelevante Meldungen wie CONFIG_I sollte separat geprüft werden, ob eine passende Regel für die verwendete Facility existiert. Hersteller- oder standortspezifische Facilities wie SYS-SW1 können von Regeln abweichen, die ausschließlich SYS erwarten. In diesem Fall ist nach der Decoder-Korrektur zusätzlich eine eigene Regelanpassung erforderlich.

Benutzerdefinierte Kopien erzeugen Upgrade-Verantwortung

Durch den Ausschluss der Originaldatei erhält die benutzerdefinierte Kopie keine zukünftigen Änderungen des ausgelieferten Cisco-IOS-Decoders. Wazuh weist in der Dokumentation ausdrücklich darauf hin, dass relevante Upstream-Änderungen nach Upgrades manuell übernommen werden müssen.

Nach jedem Wazuh-Upgrade sollte deshalb ein Vergleich erfolgen:

diff -u \
  /var/ossec/ruleset/decoders/0065-cisco-ios_decoders.xml \
  /var/ossec/etc/decoders/custom-cisco-ios_decoders.xml

Dabei müssen die eigene Korrektur und neue offizielle Decoder-Erweiterungen zusammengeführt werden. Sobald die verwendete Wazuh-Version das betroffene Format nativ korrekt verarbeitet, kann die benutzerdefinierte Kopie nach vollständigem Regressionstest wieder entfernt werden.

Änderungen versionieren

Eigene Decoder, Regeln und relevante Ausschnitte aus ossec.conf sollten in einer Versionsverwaltung dokumentiert werden. Sinnvoll sind zusätzlich:

  • betroffene Wazuh-Version,
  • repräsentative anonymisierte Testlogs,
  • erwartete Decoder-Felder,
  • erwartete Regel-ID und Alert-Stufe,
  • Datum der letzten Prüfung gegen den ausgelieferten Decoder.

Damit lässt sich nach Upgrades nachvollziehen, warum eine Abweichung vom Standard-Ruleset existiert.

Fazit

Die Ursache lag nicht grundsätzlich in der Unterstützung von Millisekunden, sondern in einer einzelnen unvollständigen prematch-Alternative für die Kombination aus zweistelligem Tag, Jahr, Millisekunden und Zeitzone.

Durch das Kopieren des vollständigen Cisco-IOS-Decoders in das benutzerdefinierte Decoder-Verzeichnis, die Korrektur des Tagesausdrucks und den Ausschluss der Originaldatei kann Wazuh beide Zeitstempelformate zuverlässig verarbeiten.

Besonders wichtig sind dabei drei Punkte: OSRegex besitzt eine von PCRE abweichende Punktsyntax, mehrere prematch-Elemente werden verkettet und eine vollständig kopierte Decoder-Datei muss nach Wazuh-Upgrades manuell mit dem ausgelieferten Ruleset abgeglichen werden.

Quellenverweise

Cisco-IOS-Decoder der untersuchten Wazuh-Version:
https://github.com/wazuh/wazuh/blob/8c41e20c34c9b455e1976b5962c79f8631b31004/ruleset/decoders/0065-cisco-ios_decoders.xml

Wazuh-Dokumentation zu benutzerdefinierten und angepassten Decodern:
https://documentation.wazuh.com/current/user-manual/ruleset/decoders/custom.html

Wazuh Decoder Syntax:
https://documentation.wazuh.com/current/user-manual/ruleset/ruleset-xml-syntax/decoders.html

Wazuh Regular Expression Syntax:
https://documentation.wazuh.com/current/user-manual/ruleset/ruleset-xml-syntax/regex.html

Wazuh-Regeln und Decoder testen:
https://documentation.wazuh.com/current/user-manual/ruleset/testing.html

Mehr zu Wazuh …

Mehr zum Wazuh Ambassador Program …

https://wazuh.slack.com/archives/C07CCCCGHHP/p1784804208375469