WatchGuard-Firewall-Logs in Wazuh: Von „No decoder matched“ zur sauberen, voll geparsten Analyse
Wer WatchGuard-Firewall-Logs über einen Syslog-Collector in Wazuh einspeist, trifft schnell auf diese frustrierende Meldung:
No decoder matched
Genau das ist Nikola passiert:
Die Logs der WatchGuard-Firewall landen per rsyslog → lokale Datei → Wazuh-Agent → Manager im System, tauchen in archives.log auf – aber keiner der gefundenen WatchGuard-Decoder von GitHub greift.
In diesem Artikel schauen wir uns an:
- warum „No decoder matched“ erscheint
- wie man einen sinnvollen Decoder-Aufbau für WatchGuard-Logs gestaltet
- wie man aus einfachen „Allow/Deny“-Regeln zu reichhaltig geparsten Events kommt
1. Ausgangssituation: WatchGuard-Logs aus SyslogCollector
Die Logs kommen von einer WatchGuard-Firewall, z. B.:
2025-11-21T00:28:01.556323+00:00 D1-ROM1-FW-A 80D802B41D509 D1-ROM1-FW firewall: msg_id="3000-0148" Allow Collector Firebox 73 udp 20 64 10.x.x.x 208.x.x.x 46616 53 geo_dst="USA" record_type="AAAA" question="mail.mydomain.com" (DNS-00)
2025-11-21T00:28:01.556528+00:00 D1-ROM1-FW-A 80D802B41D509 D1-ROM1-FW firewall: msg_id="3000-0148" Deny WAN - Aruba Firebox 40 tcp 20 239 194.x.x.x 209.x.x.x 41277 591 offset 5 S 1497867397 win 4 geo_src="BGR" geo_dst="ITA" flags="SR" duration="0" sent_pkts="1" rcvd_pkts="0" sent_bytes="40" rcvd_bytes="0" (Unhandled External Packet-00)
2025-11-21T00:28:01.946033+00:00 D1-ROM1-FW-A 80D802B41D509 D1-ROM1-FW https-proxy[4148]: msg_id="2CFF-0000" Allow Collector WAN - Aruba tcp 10.x.x.x 213.x.x.x 42018 443 msg="HTTPS Request" proxy_act="Default-HTTPS-Client" tls_profile="TLS-Client-HTTPS.Standard" ...
Typisch:
- Syslog-Prefix (Datum, Host
SysLogCollector, Pfad, Timestamp) - dann der eigentliche WatchGuard-Teil mit:
Host / Device-Name (D1-ROM1-FW-A, D1-ROM1-FW)
- Subsystem (
firewall:,https-proxy[...]) msg_id="...", Action (Allow/Deny), Richtlinie, Bytes, Protokoll, Zonen, IPs, Ports, Geo-Infos, Kategorien etc.
Die vorhandenen Community-Decoder passten nicht exakt zum Format – Ergebnis: Kein Decoder matcht → Wazuh behandelt die Zeilen nur als plain Logtext.
2. Wichtiger Punkt: „No decoder matched“ heißt nicht „Log ist kaputt“ – sondern „Decoder passt nicht“
[Bony John] hat es schön auf den Punkt gebracht:
- Wenn „No decoder matched“ angezeigt wird,→ kein vorhandener Decoder trifft auf das Format zu.
Das kann bedeuten:
- Regex des Decoders ist falsch oder zu streng
- Prematch passt nicht
- Logformat weicht von der erwarteten WatchGuard-Variante ab
- oder der „Decoder von GitHub“ war für ein anderes WatchGuard-Template geschrieben
Darum ist der richtige Weg: Eigene Decoder schreiben, passend zu den echten Logs.
3. Lösung: Parent-/Child-Decoder für WatchGuard-Logs
Statt zig Einzeldecoder im Blindflug zu testen, hat Bony ein sauberes, mehrstufiges Decoder-Design vorgeschlagen.
3.1 Parent-Decoder: Erkennen, dass es überhaupt WatchGuard ist
Beispiel:
<decoder name="watchguard">
<prematch>D1-ROM1-FW</prematch>
</decoder>
Das:
- prüft nur, ob der String
D1-ROM1-FWim Log vorkommt - markiert das Event als „WatchGuard-Log“
- dient als Anker für weitere Child-Decoder
Du könntest hier genauso gut auf firewall: oder https-proxy[ matchen – Hauptsache stabil.
3.2 Erster Child-Decoder: Basisdaten für alle Varianten
Ein erster Child-Decoder extrahiert Felder, die in den meisten Logs gleich strukturiert vorkommen, z. B.:
- Device-ID / -Host
msg_id- Action (
Allow/Deny) - Policy / Rule Name
- Bytes / Protokoll / Zonen
- Quell- und Ziel-IP/Port
Beispiel (vereinfacht):
<decoder name="watchguard">
<parent>watchguard</parent>
<regex>(\w+)\s*(\S*)\s*(\S*):\s*msg_id="(\S*)"\s*(\w*)\s*(\.*)\s+(\d+)\s*(\w+)\s*(\d*)\s*(\d*)\s+(\S*)\s*(\S*)\s*(\d*)\s*(\d*)\s*</regex>
<order>device_id,device_name,device_type,msg_id,action,policy,bytes,protocol,src_zone,dst_zone,srcip,dstip,srcport,dstport</order>
</decoder>
Das ist nur ein Beispiel – wichtig ist das Muster:
parent="watchguard"→ knüpft an das Prematch anregex→ zieht in einem Schwung die gemeinsamen Felderorder→ bennent sie sauber (action,srcip,dstip, …)
3.3 Weitere Child-Decoder: Spezifische Events (DNS, TCP Deny, HTTPS)
Nach dem Port-Block ändern sich die Logs – DNS-, TCP- und HTTPS-Events haben unterschiedliche Zusatzfelder.
Darum nutzt Bony weitere Child-Decoder für die unterschiedlichen Endstücke:
- DNS-Events, z. B.:
<decoder name="watchguard"> <parent>watchguard</parent> <regex>geo_dst="(\w*)" record_type="(\S*)" question="(\S*)" \((\S*)\)</regex> <order>geo_dst,record_type,domain,category</order> </decoder> - TCP-Deny-Events mit Geo-Daten, Flags, Duration, Packet-/Byte-Counts:
<decoder name="watchguard"> <parent>watchguard</parent> <regex>offset (\d*)\s*(\w*)\s*(\d*)\s*\.*geo_src="(\w*)"\s*geo_dst="(\S*)"\s*flags="(\S*)"\s*duration="(\d*)"\s*sent_pkts="(\d*)" rcvd_pkts="(\d*)" sent_bytes="(\d*)" rcvd_bytes="(\d*)"\s*\((\.*)\)$</regex> <order>offset,tcp_flag,seq_id,geo_src,geo_dst,flags,duration,sent_pkts,rcvd_pkts,sent_bytes,rcvd_bytes,category</order> </decoder>
Für HTTPS-Proxy-Logs (https-proxy[...]) könnte man nach dem gleichen Muster einen weiteren Child-Decoder bauen, der z. B. msg="HTTPS Request", tls_version, sni, action, app_id, Bytes etc. extrahiert.
4. Nikos eigenes Setup: Minimaldecoder + einfache Regeln
Niko hatte sich am Wochenende bereits selbst einen Einstieg gebaut:
Predecoder:
<decoder name="firewall_log">
<prematch>^\.*firewall:</prematch>
</decoder>
Dann mehrere kleine Child-Decoder:
msg_id="..."→ FeldIDfqdn_dst_match="..."→ FeldFQDN_DST(Allow)bzw.(Deny)→ FeldAction(tcp)/(udp)→ FeldPROTOCOL
Und dazu Regeln:
<group name="Watchguard,">
<rule id="110000" level="0">
<decoded_as>firewall_log</decoded_as>
<description>WatchGuard-FW-Event</description>
</rule>
<rule id="110001" level="5">
<if_sid>110000</if_sid>
<match>Deny</match>
<description>Packet Was Denied.</description>
</rule>
<rule id="110002" level="5">
<if_sid>110000</if_sid>
<match>Allow</match>
<description>Packet Was Allowed.</description>
</rule>
</group>
Das ist ein guter, pragmatischer Start:
- Man sieht schnell: „Allow“ vs. „Deny“
- Events werden schon im SIEM sichtbar hervorgehoben
Bony bestätigt das sinngemäß: Das funktioniert – aber du kannst noch viel mehr aus den Logs herausholen.
5. Wann lohnt sich ein „voller“ Decoder?
Ein minimaler Decoder reicht, wenn du:
- nur Alerts „Allow vs. Deny“ brauchst
- keine tiefe Analyse nach Geo, Ports, Policies, Bytes etc. machst
Ein „reicher“ Decoder wie der von Bony lohnt sich, wenn du:
- Dashboards zu:
Top-Policies, Top-Geo-Quellen/-Ziele, abgewiesenen Ports usw. willst
gezielte Regeln bauen möchtest:
- z. B. „Deny aus bestimmten Ländern zu sensiblen Ports mit bestimmten Flags“
später Threat Hunting machen willst, z. B.:
- SYN-Scans, auffällige Offsets, viel Traffic zu wenig IPs usw.
Dann zahlen sich saubere Felder wie geo_src, geo_dst, duration, sent_pkts, category absolut aus.
6. Fazit
Der Thread zeigt sehr schön:
- „No decoder matched“ ist keine Sackgasse – sondern der Startpunkt für maßgeschneiderte Lösungen.
- WatchGuard-Logs sind strukturiert genug, um mit Parent-/Child-Decodern sauber aufgelöst zu werden.
- Man kann klein anfangen (Allow/Deny) und schrittweise mehr Felder ergänzen.
- Mit einem guten Decoder-Set erhält man nicht nur Events, sondern ein mächtiges Netzwerk-Observability-Werkzeug.
Mehr zum Wazuh Ambassador Program …
Quelle
Dieser Artikel stammt aus dem Wazuh-Blog von m.a.x. it (veröffentlicht am 6. Dezember 2025).
Unterstützung von m.a.x. it
Bei Einführung, Betrieb und Feintuning von Wazuh (SIEM) unterstützt Sie m.a.x. it mit SIEM-Services auf Open-Source-Basis.
Über m.a.x. it Die m.a.x. Informationstechnologie AG ist seit über 30 Jahren IT-Partner mittelständischer und großer Unternehmen in München und bietet maßgeschneiderte Lösungen und Services in den Bereichen Cloud, Cybersecurity, Netzwerk, Windows, Linux und Softwareentwicklung. Sie haben eine Frage zu diesem Artikel oder brauchen Unterstützung?
