Einleitung
Netzwerkgeräte wie Access Points liefern häufig sehr hilfreiche Telemetrie: MAC-Adressen, Quell-/Ziel-IP, Protokoll und Ports. Für Security-Teams sind das ideale Datenpunkte, um laterale Bewegung, ungewöhnliche Verbindungen oder auffällige Client-Aktivität frühzeitig zu erkennen. Damit Wazuh diese Informationen regelbasiert auswerten kann, müssen die Rohlogs jedoch korrekt dekodiert werden. In der Praxis scheitert das oft daran, dass statt der Roh-Syslog-Zeile nur bereits verarbeitete JSON-Ausgaben (z. B. aus archives.json) geteilt werden – und darauf basierend Decoder gebaut werden, die später nicht matchen.
Ausgangslage / Problemstellung
Im Thread lagen Ereignisse vor, die bereits als JSON-Objekte in Wazuh vorlagen (typisch für archives.json/Indexer-Pipeline). Innerhalb dieser JSON-Struktur stand das eigentliche Geräteereignis im Feld full_log, z. B.:
[1767608555.624117131] AP MAC=60:a4:b7:47:8a:56 MAC SRC=7a:1a:09:3e:2b:00 IP SRC=192.168.100.170 IP DST=65.20.88.174 IP proto=6 SPT=64362 DPT=443
Der Wunsch: Ein Decoder, der diese Felder extrahiert (AP-MAC, Client-MAC, Src/Dst-IP, Proto, Src/Dst-Port), damit daraus Regeln und Alarme entstehen können.
Technische Analyse
Wazuh dekodiert Events in einer festen Pipeline:
- Logcollect (Agent/Manager) liest Rohzeilen.
- Predecoder erkennt ggf. Header (z. B. Syslog-Timestamp/Hostname/Program).
- Decoder matcht mit
prematch/program_nameund extrahiert Felder viaregex+order. - Rules werten die extrahierten Felder aus.
Entscheidend:
- Logs in
archives.jsonsind bereits Ergebnis dieser Pipeline (inkl. Wrapping in JSON mittimestamp,agent,location,full_logusw.). Decoder sollten daher auf die Rohzeile angewendet werden, nicht auf das JSON-Wrapper-Objekt, es sei denn, man nutzt bewusst den JSON-Decoder-Pluginweg. Für klassische Syslog-/Datei-Logs ist die Rohzeile in/var/log/tp-link.logmaßgeblich. - Ein
regex-Block in einem Decoder benötigt einprematchoderprogram_name(direkt oder vom Parent) und muss mitorderkombiniert werden, sonst ist die Extraktion nicht sauber definiert. - Wenn PCRE2 verwendet werden soll, muss
type="pcre2"gesetzt werden.
Im Thread war außerdem ein Stolperstein sichtbar: Eine der Zeilen enthielt zusätzliche Prefix-Daten (Timestamp/Host vor der Klammer). Solche Variationen führen dazu, dass ein zu „strenger“ Regex nicht matcht, wenn er exakt am Anfang der Zeile startet.
Lösung / Best Practices
1) Decoder-Strategie: Parent + Child (robust und wartbar)
Ein bewährtes Muster ist:
- Parent-Decoder: grobes Matching über
prematch(z. B. „AP MAC“) - Child-Decoder: präzise Extraktion per PCRE2-Regex
Das entspricht der im Thread vorgeschlagenen Lösung und folgt der empfohlenen Decoder-Hierarchie in Wazuh.
2) Robustes Regex-Design: Optionaler Syslog-/Prefix-Teil
Da die Rohzeile je nach rsyslog-Template oder Logquelle optional zusätzliche Header haben kann, sollte der Regex so gebaut werden, dass er nicht zwingend am Zeilenanfang starten muss. Statt ^\[ ist oft besser: „irgendwo kommt [ gefolgt von Zahlen ] AP MAC=“.
Beispiel (konzeptionell) für einen robusteren Child-Decoder:
- Suche
\[…\] AP MAC=als Anker - Extrahiere danach die Schlüsselwerte
Wichtig: Die Reihenfolge der Capture-Gruppen muss exakt der <order>-Liste entsprechen, damit Felder korrekt zugeordnet werden.
3) Feldnamen an Wazuh-Konventionen anlehnen
Für Regeln und Integrationen ist es sinnvoll, Standardfelder zu verwenden, wo möglich:
srcip,dstip,srcport,dstport,protocol
Eigene Felder (z. B.ap_mac,src_mac) sind ebenfalls möglich, sollten aber konsistent benannt werden.
4) Testen mit wazuh-logtest – aber mit der echten Rohzeile
Für Decoder-/Rule-Debugging ist wazuh-logtest das Standardwerkzeug. Wichtig ist, dass man die Roh-Logzeile (so wie sie aus /var/log/tp-link.log kommt) testet, nicht das JSON aus archives.json.
5) Alternative: JSON-Decoder nur, wenn wirklich JSON „die Quelle“ ist
Falls die Quelle tatsächlich JSON pro Zeile liefert (nicht Wazuh-internes Wrapper-JSON), kann man statt Regex-Decodern den JSON-Decoder einsetzen und Felder direkt aus JSON extrahieren. Das spart Regex-Wartung, setzt aber voraus, dass die Logquelle echtes, einzeiliges JSON liefert.
Lessons Learned / Best Practices
- Decoder werden gegen Rohlogs gebaut;
archives.jsonist ein Analyse-Artefakt, kein Decoder-Input. - Variierende Prefixe (Syslog-Header, zusätzliche Timestamps) sind der häufigste Grund für „Decoder matcht nicht“. Regex daher auf den stabilen Teil des Events ankern.
- Parent/Child-Decoder erhöhen Robustheit und erleichtern Erweiterungen (z. B. Varianten mit/ohne Ports).
- PCRE2 explizit aktivieren (
type="pcre2"), wenn man erweiterte Regex-Funktionen benötigt. - Immer mit
wazuh-logtestiterieren und dabei genau die Logzeile testen, die der Logcollector wirklich liest.
Fazit
Für TP-Link-AP-Logs (oder ähnliche Access-Point-Telemetrie) ist ein Custom-Decoder in Wazuh der Schlüssel, um aus Rohtext verwertbare Security-Signale zu machen. Entscheidend ist, den Decoder auf Basis der echten Rohereignisse aus der Logdatei zu entwickeln, Variationen in Prefix/Headers einzuplanen und die Extraktion per Parent/Child-Ansatz sauber zu strukturieren. Mit wazuh-logtest lässt sich der Decoder anschließend reproduzierbar validieren und zur Grundlage belastbarer Regeln ausbauen.
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/p1767608617853699