Wazuh agent.conf: Wildcards sauber einsammeln, aber einzelne Dateien als Multiline parsen – Grenzen von und robuste Workarounds

Einleitung (Einordnung, Relevanz für Security/SIEM/Wazuh)

In vielen Wazuh-Deployments landen Applikations- und Container-Logs als Datei-Rotation in Sammelverzeichnissen wie /var/log/docker-logs/. Der typische Ansatz ist ein breites Wildcard-Pattern (*.log) für maximale Abdeckung. Spätestens wenn einzelne Dateien Multiline-Stacktraces oder Batch-Events enthalten, wird das jedoch heikel: Diese Files müssen anders geparst werden (z. B. multi-line-regex), dürfen also nicht gleichzeitig über den generischen syslog-Reader eingelesen werden. Genau hier stößt man in der Praxis auf ein häufig missverstandenes Detail: Das Zusammenspiel aus location-Wildcard und mehreren <exclude>-Zeilen verhält sich nicht in jeder Konstellation so, wie man es intuitiv erwartet.

Ausgangslage / Problemstellung (Zusammenfassung, Symptome, Umgebung)

Die Ausgangskonfiguration folgt einem üblichen Muster:

  • Regel 1: Sammle alles aus /var/log/docker-logs/*.log als syslog.
  • Regel 2 & 3: Parse zwei spezielle Dateien (mjid.log, webs_other.log) als multi-line-regex.

Dazu werden in Regel 1 Ausschlüsse gesetzt, damit die beiden Spezialdateien nicht doppelt ingestiert werden:

<localfile>
  <log_format>syslog</log_format>
  <location>/var/log/docker-logs/*.log</location>
  <exclude>/var/log/docker-logs/mj*</exclude>
  <exclude>/var/log/docker-logs/webs_other.log</exclude>
</localfile>

Symptom:

  • Sobald das *.log-Wildcard aktiv ist, funktionieren die Multiline-Regeln nicht zuverlässig (oder es kommt zu Doppel-Parsing/Fehlklassifikation).
  • Entfernt man das *.log, greifen die Multiline-Reader wie erwartet.

Technische Analyse (Ursachen, betroffene Komponenten, Architekturbezug, Stolpersteine)

1) Warum Multiline „kaputt wirkt“, wenn das Wildcard aktiv ist

Wazuh liest Dateien über File Monitoring / Logcollector. Bei überlappenden <localfile>-Definitionen kann eine Datei aus mehreren Gründen nicht so verarbeitet werden, wie geplant:

  • Doppelte Erfassung: Die Datei wird einmal als syslog und zusätzlich als multi-line-regex gelesen. Das ist besonders bei Multiline fatal, weil ein „falscher“ Reader (syslog) Zeilen fragmentiert, während der Multiline-Reader eigentlich einen Start-Trigger und dann das Zusammenführen benötigt.
  • Race/State-Effekte: Je nach Reihenfolge und internem State (Offset/Position) kann die „erste“ Definition die Datei bereits verarbeitet und Offsets gesetzt haben, bevor der zweite Reader sauber greift.
  • Inkompatible Semantik: Multiline funktioniert zuverlässig nur, wenn die Datei exklusiv über den Multiline-Reader verarbeitet wird.

2) Das eigentliche Kernproblem: <exclude> ist nicht gleich <exclude>

In der Praxis zeigt sich ein differenziertes Verhalten:

  • Mehrere <exclude>-Zeilen können funktionieren, wenn die Ausschlüsse exakte Dateipfade sind (ohne Wildcards).
  • Mit Wildcard-Excludes (z. B. mj*) kann es passieren, dass nur ein Pattern greift oder die gesamte Exclusion-Logik nicht deterministisch wirkt.

Das erklärt die Beobachtung:

  • exclude mit mj* + ein weiterer exclude → problematisch.
  • Zwei exclude ohne Wildcards (z. B. mjid.log und webs_other.log als exakte Pfade) → funktioniert.

Diese Nuance ist wichtig: Es ist nicht „nur eine Exclude-Zeile erlaubt“, sondern eher „Wildcard-Excludes sind in Kombination/Mehrzahl nicht zuverlässig“.

3) Architekturbezug: Warum Wazuh das nicht „automatisch“ korrekt entscheidet

Wazuh ist bei <localfile>-Definitionen nicht als „Policy-Engine“ gedacht, die Konflikte auflöst. Es nimmt Konfigurationen wörtlich und arbeitet sie ab. Sobald ein File in mehreren lokalen File-Inputs auftaucht, muss der Betreiber sicherstellen, dass:

  • jeder Logstrom eindeutig einem Reader zugeordnet ist,
  • Multiline-Dateien nicht parallel über generische Wildcards abgedeckt werden,
  • und Excludes nicht auf nicht-deterministische Musterkombinationen setzen.

Lösung / Best Practices (konkrete Schritte, Konfigurationen, Reihenfolge, Side-Effects)

Best Practice 1: Exakte Excludes statt Wildcard-Excludes verwenden

Wenn es wirklich nur zwei Dateien sind: keine Wildcards im Exclude. Damit bleibt das Verhalten stabil und nachvollziehbar.

<localfile>
  <log_format>syslog</log_format>
  <location>/var/log/docker-logs/*.log</location>
  <exclude>/var/log/docker-logs/mjid.log</exclude>
  <exclude>/var/log/docker-logs/webs_other.log</exclude>
</localfile>

<localfile>
  <log_format>multi-line-regex</log_format>
  <location>/var/log/docker-logs/mjid.log</location>
  <multiline_regex type="pcre2" match="start" replace="wspace">\d\d\d\d-\d\d-\d\d</multiline_regex>
</localfile>

<localfile>
  <log_format>multi-line-regex</log_format>
  <location>/var/log/docker-logs/webs_other.log</location>
  <multiline_regex type="pcre2" match="start" replace="wspace">^Traceback</multiline_regex>
</localfile>

Warum das gut ist:

  • Keine Pattern-Mehrdeutigkeit.
  • Multiline-Dateien sind exklusiv dem Multiline-Reader zugeordnet.
  • Das generische *.log deckt weiterhin alles andere ab.

Best Practice 2: Multiline-Logs konsequent umbenennen oder separieren

Wenn künftig mehr Multiline-Dateien hinzukommen (und du nicht jede einzeln im Exclude pflegen willst), ist eine strukturelle Trennung meist die sauberste Lösung:

Option A: Namenskonvention

  • Alle Multiline-Files bekommen ein Prefix, z. B. ml_*.log
  • Dann reicht ein einziges Exclude-Pattern (wenn Wildcards stabil greifen) oder du drehst das Prinzip um:

Beispiel:

  • Sammelregel: /var/log/docker-logs/*.log
  • Multiline in separatem Namensraum: /var/log/docker-logs/ml_*.log
  • Exclude nur: /var/log/docker-logs/ml_*.log

Option B: Separates Verzeichnis

  • Standardlogs: /var/log/docker-logs/*.log
  • Multiline: /var/log/docker-logs-multiline/*.log

Dann gibt es gar keine Überschneidung mehr, und die Config bleibt wartbar.

Best Practice 3: Wildcard im location enger schneiden, statt Excludes komplex zu machen

Wenn du alle „normalen“ Logs an einem Merkmal erkennst (Suffix, Prefix, Unterordner), ist es oft besser, das location-Pattern so zu wählen, dass Multiline-Dateien gar nicht erst gematcht werden.

Beispiel-Idee:

  • Normale Logs: *_sys.log
  • Multiline: *_ml.log

Dann:

  • location>*_sys.log</location> für syslog
  • location>*_ml.log</location> für multiline

Side-Effects, die du einplanen solltest

  • Doppel-Ingestion produziert häufig „komische“ Alerts: Parsen als syslog kann Felder/Decoder triggern, die bei Multiline nicht passen.
  • Offsets/Read-State: Nach Umstellung kann es sein, dass Dateien erneut eingelesen werden (je nach Logcollector-State). In produktiven Umgebungen ein Wartungsfenster/Monitoring einplanen.

Lessons Learned / Best Practices (präventive Maßnahmen, Betrieb, Skalierung)

  • Eindeutigkeit schlägt Eleganz: Lieber klare, nicht überlappende <localfile>-Definitionen als „ein Pattern für alles“ mit vielen Ausnahmen.
  • Wildcard-Excludes sparsam einsetzen: Besonders dann, wenn mehrere Excludes kombiniert werden müssen oder du deterministisches Verhalten brauchst.
  • Log-Design gehört zur Security-Pipeline: Schon beim Container/Applikations-Logging feste Regeln für Multiline vs. Singleline definieren (Dateinamen oder Verzeichnisstruktur).
  • Multiline ist ein Spezialfall: Behandle Multiline-Dateien immer als „first-class citizens“ mit exklusiven Readern und möglichst ohne Überschneidungen mit Sammelregeln.

Fazit (knappe Zusammenfassung mit Mehrwert)

Wenn Multiline-Dateien in Wazuh parallel von einer generischen Wildcard-Regel (*.log als syslog) erfasst werden, ist Fehlverhalten vorprogrammiert: Multiline wird fragmentiert, Zustände überschneiden sich, und Excludes mit Wildcards können in Kombination unzuverlässig wirken. Stabil wird es, wenn du Multiline-Dateien entweder (a) mit exakten Excludes ohne Wildcards aus der Sammelregel herausnimmst oder (b) Multiline-Logs über Namenskonventionen bzw. separate Verzeichnisse vollständig von den „normalen“ Logs trennst. Das reduziert Komplexität, verhindert Doppel-Ingestion und macht deine agent.conf langfristig wartbar.


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/p1770200656015799