pfSense-Logs ohne Hostname (RFC3164/BSD) in Wazuh korrekt dekodieren: Predecoder-Shift beheben und robuste Custom-Decoder/Rules bauen

Einleitung

pfSense ist in vielen Umgebungen die zentrale Telemetriequelle für Firewall- und Filterlog-Events. Wazuh kann diese Logs hervorragend korrelieren und alarmieren – allerdings nur, wenn die Syslog-Nachrichten in einer Form ankommen, die Wazuh sauber „pre-decodieren“ kann. Genau hier scheitern pfSense-Setups regelmäßig: pfSense sendet in der Praxis häufig BSD/RFC3164-ähnliche Messages ohne Hostname-Feld, was in Wazuh zu einer Spaltenverschiebung führt. Das Ergebnis sind leere program_name-Felder, nicht matchende Standarddecoder (z. B. pfSense Decoder 0455) und am Ende: keine Decodes, keine Regeln, keine Alerts.

Dieser Beitrag zeigt, warum das passiert, welche zwei sauberen Lösungswege sich etabliert haben (Log-Format upstream korrigieren oder in Wazuh custom decodieren) und wie man daraus stabile Regeln ableitet – auch in einer Single-Node Docker Manager-Umgebung.

Ausgangslage / Problemstellung

Umgebung: Wazuh Manager als Single-node Docker, pfSense sendet Syslog via Rsyslog im BSD-Format (RFC3164). Logs kommen an, aber Decoding schlägt fehl.

Log-Beispiel (ohne Hostname zwischen Timestamp und Tag):
Feb 11 18:15:43 filterlog[00000]: 8,,,1000000000,vmx1,match,block,in,4,0x88,,48,6840,0,none,6,tcp,48,1.2.3.4,5.6.7.8,65435,80,0,S,1000751876,,0,,mss;wscale;eol

Wazuh-logtest (Symptom):

  • Phase 1 (Pre-decoding): hostname = filterlog[00000]: und program_name leer
  • Phase 2 (Decoding): kein Decoder matcht, weil der Standarddecoder program_name=filterlog erwartet (strict program_name check)

Damit ist die Ursache klar: nicht „pfSense Decoder kaputt“, sondern Predecoder interpretiert das Tag als Hostname, weil das Hostname-Feld fehlt.

Technische Analyse

1) Warum das Hostname-Feld so wichtig ist

Im klassischen Syslog (BSD/RFC3164-typisch) ist die erwartete Struktur sinngemäß:

TIMESTAMP HOSTNAME TAG[PID]: MESSAGE

Fehlt der Hostname, rutscht TAG[PID]: in das Hostname-Slot. Genau dann wird program_name nicht befüllt, und Decoder, die auf <program_name>filterlog</program_name> matchen, greifen nicht mehr. Der Effekt ist ein „Column Shift“.

Dass Geräte RFC3164-ähnliche Nachrichten „unvollständig“ senden, ist in der Praxis häufig – und wird in der Syslog-Welt auch von Parsern adressiert (z. B. spezielle RFC3164-Parser, die mit malformed messages umgehen).

2) pfSense und Remote Syslog: „funktioniert“, aber nicht immer parserfreundlich

pfSense kann Logs an einen Remote Syslog Server senden, die Details hängen jedoch stark von Format/Transport/Forwarder ab.
In mehreren Community-Setups wird explizit beschrieben, dass pfSense oft keinen Hostname in den Syslog-Header setzt, was bei Wazuh den Predecoder stört.

3) Wazuh-Decoder-Strategie: Parent + Sibling/Child Decoder statt „Alles in einem Regex“

Wazuh unterstützt eine saubere Decoder-Architektur: ein Parent-Decoder mit prematch, darauf aufbauende Child/Sibling Decoder, die Stück für Stück Felder extrahieren (inkl. offset="after_regex").
Diese Strategie passt besonders gut zu pfSense filterlog, weil die Payload CSV-ähnlich ist und man schrittweise (action, protocol, srcip/dstip, ports, length etc.) extrahieren kann.

Lösung / Best Practices

Es gibt zwei robuste Ansätze. In der Praxis ist Ansatz B (Custom Decoder) oft der schnellste, weil er unabhängig vom Upstream-Logformat ist.

Ansatz A: Syslog upstream „reparieren“ (Hostname ergänzen)

Wenn Sie die Logpipeline kontrollieren (rsyslog/syslog-ng/relay), können Sie die pfSense Messages so normalisieren, dass ein Hostname vorhanden ist. Dadurch funktionieren Standard-Decoder häufiger „out of the box“. Ein praxisnaher Workaround für „missing hostname“ wird z. B. in einem pfSense→Wazuh-Integrationstutorial beschrieben.

Vorteile: Standarddecoder können wieder greifen, konsistentere Syslog-Header.
Nachteile: Eingriff in Logpipeline, potenziell mehrere Forwarder/Quellen.

Ansatz B: Custom Decoder in Wazuh für „hostname-loses filterlog“

Der nachhaltige Fix ist ein eigener Decoder, der explizit auf das pfSense-Logformat ohne Hostname zugeschnitten ist. Wazuh empfiehlt Custom-Decoders explizit und dokumentiert auch, wie man eigene Decoder upgrade-stabil in /var/ossec/etc/decoders/ pflegt.

Beispiel-Decoder (konzeptionell wie im Thread erprobt):

  • Parent: prematch auf filterlog[\d+]
  • Child 1: extrahiert id und action aus den frühen CSV-Feldern
  • Child 2/3: extrahiert protocol, srcip, dstip, srcport, dstport
  • Optional: length oder weitere Felder

Wichtig dabei:

  • Der Predecoder wird weiterhin hostname=filterlog[PID]: zeigen – das ist ok. Entscheidend ist, dass der Custom Decoder nicht auf program_name angewiesen ist, sondern auf prematch/Regex in der Message.
  • Decoder modular halten (mehrere Child-Decoder) statt einen fragilen Megaregex.

Regeln: Von „Decoder matched“ zu verwertbaren Alerts

Im Thread wurden Rules erstellt, die auf dem Custom Decoder aufsetzen und auf action=block triggern, plus Korrelation (frequency/timeframe) und Port-spezifische Regeln (SSH/RDP/443 etc.).

Das ist grundsätzlich solide – ein paar Best-Practice-Punkte machen es robuster:

  1. Baselinerule level=0 als Gruppierung
    Eine „sammelt alles“-Rule mit decoded_as ist gut, um pfSense-Events einheitlich zu taggen (z. B. pfsense,). Danach folgen Spezialisierungen.
  2. Block-Rule als zentrale Abzweigung
    Eine Rule, die action=block matcht, sollte nicht no_log tragen, wenn Sie darauf Korrelationen und spezifische Use-Cases bauen. no_log verhindert die Speicherung des Alerts und kann spätere Ketten/Visibility erschweren (je nach Pipeline). Besser: level niedrig halten oder per Group/Index/Filter steuern, statt zu unterdrücken.
  3. Korrelation „same_source_ip“ sauber testen
    Die Korrelation über if_matched_sid + <same_source_ip /> ist ein sinnvoller Start. In der Praxis lohnt es sich, zusätzlich Ports oder Destination zu berücksichtigen (z. B. same_source_ip + same_dstport), um NAT/Scanning-Noise besser zu trennen – abhängig vom Umfeld.
  4. Interne IP-Ranges: korrekt modellieren
    Mehrere <srcip>-Tags in einer Regel können je nach Parser-/Rule-Logik missverständlich sein (AND/OR-Verhalten). In vielen Fällen ist es stabiler, das mit einer passenden Regex oder CIDR-Logik in getrennten Regeln zu modellieren (z. B. eine Regel für 172.16/12, eine für 192.168/16), damit das Verhalten eindeutig bleibt.
  5. „Forge & Append“-Test als Betriebsmuster
    Das Vorgehen, Testlogs im exakten Format zu erzeugen und in die Syslog-Datei zu schreiben, ist eine der zuverlässigsten Methoden, um Decoder+Rules zu validieren, bevor man sie in Produktion ernst nimmt.

Lessons Learned / Best Practices

  • pfSense liefert häufig RFC3164-ähnliche Syslog-Nachrichten ohne Hostname; Wazuhs Predecoder reagiert darauf mit Column Shift.
  • Wenn Standarddecoder streng auf program_name matchen, ist ein Custom Decoder der pragmatischste Fix: nicht gegen den Predecoder kämpfen, sondern auf prematch/Regex in der Message setzen.
  • Decoder modular bauen (Parent + Child/Sibling, after_regex) – das ist wartbarer und weniger fragil als ein einziger großer Regex.
  • Regeln zuerst breit (Baseline), dann fein (block + Service-Ports + Korrelation). Noise-Management lieber über Severity/Groups/Dashboards als über no_log, wenn man forensische Nachvollziehbarkeit behalten möchte.

Fazit

Der pfSense Decoder „0455“ ist in solchen Fällen nicht „defekt“, sondern wird durch ein nicht-hostname-konformes Syslog-Header-Format ausgebremst. Sobald der Hostname fehlt, verschiebt sich die Interpretation im Predecoder und program_name bleibt leer – Standarddecoder greifen dann nicht mehr. Die praxistauglichste Lösung ist ein dedizierter Custom Decoder, der filterlog[...] per prematch erkennt und die CSV-Felder stufenweise extrahiert. Darauf aufbauende Regeln (block, Korrelation, Port-Fokus) liefern sofort verwertbare Alerts – auch in Docker-Single-Node-Setups.

Quellen (Copy & Paste)

https://documentation.wazuh.com/current/user-manual/ruleset/decoders/custom.html
https://documentation.wazuh.com/current/user-manual/ruleset/ruleset-xml-syntax/decoders.html
https://marceltc.com/sending-pfsense-syslogs-to-wazuh-siem/
https://docs.netgate.com/pfsense/en/latest/monitoring/logs/remote.html
https://www.rsyslog.com/doc/configuration/modules/pmrfc3164.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/C07CCCCGHHP/p1770832160036299