In der Praxis landen Citrix ADC (ehem. NetScaler) Syslog-Zeilen oft in einem Format, das stark an klassische ns.log-/Syslog-Ausgaben erinnert (z. B. 0-PPE-0 : TCP CONN_TERMINATE …). Dieses Muster matcht schnell auf generische/Default-Decoder (z. B. netscaler), sodass eigene Felder nicht wie gewünscht extrahiert werden oder „falsch“ interpretiert wirken. Ein typisches Citrix-Beispiel sieht u. a. so aus: 0-PPE-0 : TCP CONN_TERMINATE … Source … Destination … Citrix Support
Unten ist ein praxistauglicher Weg, wie du:
- die echte Roh-Zeile verifizierst,
- einen eigenen Parent/Child-Decoder definierst, der vor dem Default greift, und
- optional das Default-Decoding gezielt ausschließt, wenn nötig.
1) Erst prüfen: Welche Log-Zeile kommt wirklich bei Wazuh an?
Bevor du Decoder schreibst, stelle sicher, dass du die exakte Logline siehst, die der Manager analysiert. Dafür sind archives.json (Raw Events) extrem hilfreich.
Wenn Archive-Logging bei dir deaktiviert ist, kannst du testweise alles als JSON archivieren. Wazuh dokumentiert das Event-Logging inkl. Archive-Output und der Option logall_json.
Check (Manager):
# Beispiel: Archive-Events durchsuchen (Pfad je nach Setup)
grep -i "ADC\|SSLVPN\|CONN_TERMINATE\|HTTPREQUEST" /var/ossec/logs/archives/archives.json | tail -n 5
2) Warum matcht der Default-Decoder?
Wazuh verarbeitet Decoder nach dem „First match wins“-Prinzip innerhalb der Decoder-Chain (Parent → Child). Wenn dein ADC-Log vom vorhandenen netscaler-Parent bereits „gut genug“ erkannt wird, laufen deine Child-Decoder möglicherweise unter diesem Parent – oder du bekommst ein Ergebnis, das nicht deiner Erwartung entspricht.
Genau deshalb ist der wichtigste Hebel: ein eigener Parent-Decoder mit einem eindeutigeren prematch, der deine ADC-Variante zuverlässiger erkennt.
Allgemeine Grundlagen zu Decodern (Parent/Child, Regex, Order, etc.) findest du in der Wazuh Decoder-Doku.
3) Empfohlener Ansatz: Eigener Parent + gezielte Child-Decoder
3.1 Parent-Decoder so bauen, dass er nur deine ADC-Zeilen abgreift
Beispiel: Deine Logs enthalten u. a. SSLVPN HTTPREQUEST oder TCP CONN_TERMINATE. Das ist ein gutes Erkennungsmerkmal (Citrix zeigt sehr ähnliche Patterns in Beispielen). Citrix Support
/var/ossec/etc/decoders/local_decoder.xml (oder eigene Datei im Decoder-Verzeichnis):
<decoder name="citrix_adc">
<!-- prematch: möglichst eindeutig, aber nicht zu eng -->
<prematch>0-PPE-0\s:\s(default\s)?(SSLVPN|TCP)\s</prematch>
</decoder>
Hinweis: Wazuh empfiehlt Custom Decoder über
local_decoder.xmloder unter/var/ossec/etc/decoders/. documentation.wazuh.com
3.2 Child-Decoder: die „Header“-Struktur extrahieren
Aus dem Thread-Vorschlag lässt sich ein robuster Start bauen: ADC-Name, PPE, Category/Facility, Protokoll, Event-Typ, Log-ID.
<decoder name="citrix_adc_header">
<parent>citrix_adc</parent>
<regex>\d{1,2}\/\d{1,2}\/\d{4}:\d{2}:\d{2}:\d{2}\sGMT\s(\S+)\s(\S+)\s:\s(\S+)\s(\S+)\s(\S+)\s(\d+)\s0\s:</regex>
<order>adc_name,ppe,category,protocol,event_type,log_id</order>
</decoder>
3.3 Child-Decoder: wichtige Felder aus dem „Message“-Teil
Je nach Logtyp (HTTPREQUEST vs. CONN_TERMINATE) kannst du weitere Decoder ergänzen. Beispiel:
<decoder name="citrix_adc_conn_terminate">
<parent>citrix_adc</parent>
<regex>Source\s(\d+\.\d+\.\d+\.\d+):(\d+)\s-\sDestination\s(\d+\.\d+\.\d+\.\d+):(\d+)</regex>
<order>src_ip,src_port,dst_ip,dst_port</order>
</decoder>
<decoder name="citrix_adc_http_request">
<parent>citrix_adc</parent>
<regex>\s(GET|POST|PUT|DELETE|HEAD|OPTIONS)\s(\S+)\s-\s-\s*$</regex>
<order>http_method,http_path</order>
</decoder>
4) „Default netscaler soll gar nicht matchen“: Decoder gezielt ausschließen (optional)
Wenn du wirklich verhindern willst, dass ein bestimmter Decoder geladen wird (z. B. weil er deine Daten dauerhaft falsch „einsortiert“), bietet Wazuh die Option decoder_exclude. Damit kannst du Decoder-Dateien vom Laden ausnehmen. documentation.wazuh.com
Beispiel (in ossec.conf):
<ruleset>
<decoder_exclude>netscaler_decoders.xml</decoder_exclude>
</ruleset>
Wichtig: Das ist ein „großer Hammer“. Du verlierst damit jede Standard-Erkennung, die über diese Decoder-Datei kommt. In Multi-Use-Umgebungen ist es meist besser, den eigenen Parent so eindeutig zu machen, dass er sauber gewinnt, statt global auszuschließen.
5) Testen: Decoder + Rules
- Decoder testen mit
wazuh-logtest(auf dem Manager). - Erst wenn Phase 2 die Felder zeigt, Regeln bauen.
Als Einstieg kannst du eine „Marker“-Rule bauen:
<group name="citrix_adc,network">
<rule id="100200" level="3">
<decoded_as>citrix_adc</decoded_as>
<description>Citrix ADC event observed: $(protocol) $(event_type) on $(adc_name)</description>
</rule>
</group>
Typische Stolperfallen
- Rohdaten stimmen nicht: Du testest mit einer „händisch kopierten“ Zeile, aber in
archives.jsonkommt sie anders an → immer zuerst Raw prüfen. - Prematch zu generisch: Dann matchen zu viele Dinge, oder du konkurrierst weiter mit
netscaler. - Zu viele Child-Decoder mit gleichem Namen: In Wazuh ist es sauberer, Child-Decoder eindeutig zu benennen (auch wenn es technisch teils funktioniert).
- Regex zu „greedy“: Nutze lieber mehrere kleine Decoder als einen riesigen, der bei Varianten bricht.
Weiterführende Quellen
- Wazuh: Decoder-Übersicht & Konzepte (Parent/Child, Regex, order).
- Wazuh: Custom Decoder, Ablageorte und
decoder_exclude. documentation.wazuh.com - Wazuh: Event Logging / Archive Logs (Rohdaten in
archives.json). - Citrix ADC Beispiel-Logformat mit
0-PPE-0,TCP CONN_TERMINATEusw. Citrix Support
https://wazuh.slack.com/archives/C0A933R8E/p1766139139131129