Tipps & Tricks

Splunk Connect for Syslog: einsatzfertige, skalierbare Syslog-Datenaufnahme – Teil 4

In den vorangegangenen Teilen dieser Reihe haben wir euch einen Überblick gegeben und die Konfigurationsdetails vorgestellt, die ihr benötigt, um Quellen, die Splunk Connect for Syslog bereits vorsieht, einzuspeisen; außerdem habt ihr gelernt, Anpassungen und Überschreibungen zu konfigurieren, die euer Unternehmen braucht. Damit bleibt eine Schlüsselfunktion von SC4S übrig, die wir noch nicht behandelt haben, nämlich die Erweiterung der Plattform selbst.

In diesem Beitrag gehen wir schrittweise die Konfiguration einer völlig neuen Datenquelle durch – eine, die SC4S nicht von Haus aus anspricht. Machen wir uns also an die Aufgabe, SC4S um die Unterstützung einer neuen Datenquelle zu erweitern!

SC4S-Entwicklungsübersicht

Vorbereitung

Bevor ihr mit der Erstellung eines Log-Pfads (Filters) für ein neues Gerät beginnt, solltet ihr einige wichtige Fragen beantworten:

  • Handelt es sich um ein völlig neues Gerät, oder ist es mit einem vorhandenen Gerät verwandt (wie etwa ein neues Cisco-Gerät, das auf IOS basiert)? Wenn Letzteres der Fall ist, ist es am besten, ein Issue auf GitHub zu erstellen, damit das Splunk-Entwicklungsteam dieses Gerät/Format zur bestehenden Unterstützung von Herstellern/Gerätefamilien hinzufügen kann. SC4S entwickelt sich schnell weiter, sodass oft schon in wenigen Wochen Unterstützung für neue Geräte ab Werk verfügbar ist.
  • Ist das Gerät oder die Datenquelle in der Branche gebräuchlich? Wir bieten derzeit zwar Unterstützung für die meisten Datenquellen, aber SC4S deckt keineswegs alles ab. Wenn das Gerät häufig verwendet wird und z. B. eine Firewall eines bekannten Anbieters ist (und nicht ein Syslog von einer hausintern entwickelten App), dann ist es vielleicht am besten, ein Issue zu starten (und möglicherweise Code/PR beizusteuern), statt sich einen Selbstversuch zu wagen.
  • Wurde in der Community bereits eine Lösung für die Datenquelle entwickelt? In den entsprechenden Slack-Kanälen nachzufragen, ist immer ein guter erster Schritt.
  • Gibt es bereits eine Splunk-App und/oder ein TA für dieses Gerät? Die Antwort auf diese Frage ist kritisch, weil sie bestimmt, welches Ausgabeformat (an Splunk) ihr braucht, weil das TA es erwartet. Seht in der Splunkbase und in der Anbieterdokumentation nach, ob ihr eure Vermutung bestätigen könnt.
  • Ist das vom Gerät verwendete Ausgabeformat gut dokumentiert? Die meisten Anbieter dokumentieren die „nackte“ (on the wire) Syslog-Nachricht nicht ordentlich oder gar nicht, also müsst ihr euch diese Informationen selbst verschaffen. (Das behandeln wir weiter unten.)

Die Antworten auf die vorstehenden Fragen geben euch Hilfestellung, wenn ihr euch daran macht, die Plattform um einen neuen Log-Pfad zu erweitern. Beginnen wir mit ein paar Hintergrundinformationen dazu, wie die grundlegende Struktur einer syslog-ng-Konfiguration aussieht – diese Kenntnis braucht ihr für die Erstellung eines Log-Pfads.

Aufbau von syslog-ng-Konfigurationsdateien

Hier sehen wir die allgemeine Struktur einer syslog-ng-Konfigurationsdatei. Deren Syntax, die ihrerseits eine Programmiersprache ist, bietet eine ganze Menge von Wegen, die ans Ziel führen. Aber alle folgen dem gleichen Grundschema:

In SC4S ist das meiste davon über die in Teil 3 dieser Serie beschriebenen Konfigurationsmechanismen abstrahiert, sodass Administratoren nicht alle Feinheiten der syslog-ng-Syntax beherrschen müssen. Die Struktur eines Log-Pfads wird aber bei der Entwicklung eines neuen Pfades sofort deutlich, und es ist wichtig, dass ihr einen Begriff davon habt, wie die Teile zusammenwirken.

Syslog-ng-Ereignisfluss

Bei einer typischen syslog-ng-Konfiguration – einschließlich SC4S – gibt es mehrere Log-Pfade, einen für jede Sorte von Ereignissen (Geräten). Diese Ereignisformate werden normalerweise von den Anbietern selbst festgelegt und sollten den veröffentlichten syslog-Standards (RFC 3164 oder RFC 5424) entsprechen. Viele weichen jedoch von diesen Standards ab, und das muss man bei den Log-Pfaden berücksichtigen.

In der endgültigen Konfigurationsdatei fließen die Ereignisse von oben nach unten, wobei jedes einzelne von den Filtern in jedem Log-Pfad getestet wird, ob das Ereignis dorthin gehört. Obwohl das Schema oben Filter als separate Einheit zeigt, fungieren in Wirklichkeit alle Stufen (mit Ausnahme der endgültigen Zielrichtlinie) als Filter (oder Test). Das bedeutet, dass der Quellblock selbst als Filter fungiert: Wenn der Quellblock besagt: „An UDP-Port 5000 sammeln“ und das Ereignis taucht an UDP-Port 514 auf, dann wird dieser Log-Pfad nicht für dieses Ereignis verwendet. In ähnlicher Weise kann das Parsen von Nachrichten ebenfalls als Filter fungieren (falls gewünscht) und Ereignisse aus einem Log-Pfad ausschließen, wenn das Parsen fehlschlägt. Wenn das Ereignis lange genug in einem Log-Pfad „überlebt“, wird es schließlich an ein oder mehrere vom Admin festgelegte Ziele gesendet.

Ein Ereignis kann prinzipiell mit mehr als einem Log-Pfad übereinstimmen. Wir raten in SC4S aber davon ab und konfigurieren tatsächlich jeden Log-Pfad mit einem Flag, sodass die Verarbeitung beendet wird, sobald das Ereignis von einem bestimmten Log-Pfad erfolgreich verarbeitet ist. Hier gilt: Wer zuerst kommt, mahlt zuerst. Dies ist auch die einzige Stelle in syslog-ng, an der die Dateinamen von Log-Pfaden eine Rolle spielen: Log-Pfade werden nämlich nach dem Dateinamen in lexikografischer Reihenfolge (im Wesentlichen alphabetisch) verarbeitet. Intern sorgt SC4S mit geeigneten Dateinamen dafür, dass bestimmte Log-Pfade vor (oder nach) allen anderen verarbeitet werden. Dadurch wird geklärt, wer „zuerst mahlt“, falls auf Basis der Filterung mehr als ein Log-Pfad ausgelöst wird. Diese Technik wird nur für Reserve-Log-Pfade (catchall) und „NULL-Warteschlangen“-Log-Pfade verwendet, sie sollte also keine Auswirkungen auf die in der Praxis entwickelten Log-Pfade haben.

Wir werden uns nun eine Schlüsselfunktion von SC4S ansehen, die für die Erstellung von Log-Pfaden grundlegend ist. Erinnert ihr euch an den Anfang von Teil 3, wo wir die Umgebungsvariablen in der env_file erörtert haben? Wenn wir dort eine HEC-Endpunkt-URL und ein Token mit einer Umgebungsvariable angeben, wie übersetzt sich das in die syslog-ng-Syntax, die ja letztlich „hart kodiert“ sein muss? Die Antwort lautet: Mit Templating. Templating ist ein wichtiger Schritt, mit dem die zugrundeliegende Syntax für den Administrator abstrahiert wird – und ebenso wichtig, weil er die Erstellung von Log-Pfaden wesentlich einfacher macht.

Log-Pfad-Vorlagen (gomplate)

Die Syntax von syslog-ng ist sehr streng, und obwohl sie einer kompletten Programmiersprache nahekommt, fehlen ihr doch einige wichtige Konstrukte, insbesondere die Fähigkeit, mit der laufenden Umgebung zu interagieren und ihre Konfiguration auf der Grundlage bedingter Tests von Umgebungsvariablen anzupassen. Wenn syslog-ng instanziiert wird, muss die Konfiguration zur Laufzeit verfestigt werden. Daher benötigt SC4S einen Mechanismus, der es erlaubt, diese feste Konfiguration dynamisch kurz vor dem Start von syslog-ng zu erstellen. Gebt hierzu „gomplate“ oder „go templates“ ein.

Der Templating-Prozess macht es möglich, dass Umgebungsvariablen die von SC4S verwendete endgültige syslog-ng-Konfiguration bestimmen. Betrachten wir z. B. diese Umgebungsvariable:

SC4S_SOURCE_UDP_SO_RCVBUFF=33554432

Wie findet der Wert dieser Variable seinen Weg in die endgültige Konfiguration? Der Schlüssel ist das Templating – die syslog-ng-Quellkonfiguration innerhalb des Containers ist nicht hart kodiert, sondern sieht aus der Perspektive des UDP-Empfangspuffers wie folgt aus:

so-rcvbuf({{getenv "SC4S_SOURCE_UDP_SO_RCVBUFF" "1703936"}})

Alles innerhalb der doppelten geschweiften Klammern ist Teil der Vorlage (die selbst eine eigene Sprache ist) und dazu da, auf der Grundlage der Einstellungen der Umgebungsvariablen bedingt Konfigurationselemente einzufügen. Das Ergebnis ist die folgende endgültige Konfiguration, die den Standardwert (1703936) durch den Wert aus der Variable ersetzt:

so-rcvbuf(33554432)

Bei dem Beispiel oben handelt es sich um eine einfache Ersetzung; tatsächlich könnt ihr auch komplexere bedingte Ersetzungen vornehmen:

{{- if or (conv.ToBool (getenv "SC4S_ARCHIVE_GLOBAL" "no")) (conv.ToBool (getenv "SC4S_ARCHIVE_CISCO_ASA" "no")) }}
    destination(d_archive);
{{- end}}

Dieses Konstrukt fügt das alternative Archivierungsziel in die Konfiguration ein, wenn eine der ARCHIVE-Variablen auf „yes“ gesetzt ist. Falls in der env_file keine der beiden Variablen festgelegt ist oder beide auf den Wert „no“ gesetzt sind, wird der Text in der if/end-Bedingung nicht in die Konfiguration eingefügt.

Wir wollen uns nun der Erstellung eines Log-Pfads widmen, der stark von diesem Templating Gebrauch macht. Es gibt jedoch ein paar Punkte, die wir erledigen müssen, bevor wir mit dem Schreiben des Log-Pfads beginnen – sie werden uns diesen Prozess erleichtern. Ein entscheidender Schritt – nachdem wir gemäß der „Vorbereitung“ (siehe oben) geprüft haben, ob ein neuer Log-Pfad wirklich erforderlich ist – besteht darin, dass wir uns ein geeignetes unbearbeitetes Rohereignis besorgen, mit dem wir arbeiten können.

Erfassung von Rohdaten

Möglicherweise habt ihr schon Erfahrung mit dem Sammeln von Rohdatenproben bei der Konfiguration von SC4S gemacht, insbesondere wenn Ereignisse mit den falschen Metadaten (Sourcetyp usw.) in Splunk landen. Diese Aufgabe ist entscheidend für die Entwicklung von Log-Pfaden und sollte den ersten technischen Schritt darstellen. Hierfür gibt es eine Reihe von Möglichkeiten; die beiden gängigsten sind tcpdump und die Verwendung von SC4S selbst. Die Details dazu sind hier dokumentiert; wir fassen sie im Folgenden kurz zusammen und kommen darauf in unserer exemplarischen Darstellung zurück:

  • Führt tcpdump mit den entsprechenden Optionen auf einem SC4S-Host aus, und sucht nach der verräterischen -Zeichenfolge (z.B. <134>) und dem darauf folgenden Text. Die Nachricht wird wahrscheinlich zwischen „Müll“-Zeichen auftreten, sollte aber klar genug sein, um sie zu erkennen, insbesondere den wichtigsten Teil, den Header.
  • Legt die Variable SC4S_SOURCE_STORE_RAWMSG=yes fest und sucht in Splunk nach dem Feld RAWMSG, wenn ein Beispielereignis an SC4S gesendet wird. Wenn ihr das Ereignis in Splunk anzeigt (es sollte einen der beiden folgenden Reserve-Sourcetypen aufweisen: sc4s:fallback oder nix:syslog), dann seht ihr darüber hinaus noch weitere Felder; diese werden bei der Entwicklung unseres Log-Pfads sehr nützlich sein.
  • Zum „Abspielen“ eines Rohereignisses (entweder auf dem Gerät selbst erfasst oder außer der Reihe bereitgestellt) führt einfach echo "<contents of RAWMSG>" > /dev/udp/<SC4S IP addr>/514 aus

Jetzt haben wir die Daten, die wir benötigen, um einen Beispiel-Log-Pfad anzulegen. Also los!

Exemplarische Darstellung einer SC4S-Log-Pfadentwicklung

Log-Pfad-Entwicklung – vor dem Start

Es gibt zwei Arten von Log-Pfaden in SC4S: „einfache“ und „herkömmliche“. Einfache Log-Pfade könnt ihr verwenden, wenn das Gerät imstande ist, auf einem eindeutigen Port zu senden, und eine minimale, rein protokollbasierte Analyse ausreicht, um einen einzelnen Sourcetyp für das Ereignis zu bestimmen. Diese Art kann vollständig über Umgebungsvariablen konfiguriert werden, die Entwicklung eines dedizierten Log-Pfads ist nicht erforderlich. 

Wenn die Gerätefamilie hingegen mehrere Sourcetypen erfordert (wie z. B. bei Palo Alto), muss ein herkömmlicher Log-Pfad mit umfassenderem Parsing entwickelt werden. Im Rahmen dieser exemplarischen Darstellung werden wir also zuerst bestimmen, ob unser neues Gerät mit einem einfachen Log-Pfad unterstützt werden kann oder ob ein herkömmlicher Pfad entwickelt werden muss.

Wir nehmen das Produkt StealthINTERCEPT von Stealthbits als Beispiel für den neuen Log-Pfad. Die Konfiguration der App und des Geräts für den Syslog-Betrieb ist insofern typisch, als kein „nacktes“ On-the-wire-Muster zur Verfügung steht. Daher müssen wir tcpdump oder SC4S verwenden, damit wir wie oben beschrieben ein Rohmuster bekommen.

Die folgenden Schritte zum Erstellen eines Log-Pfads, der die StealthINTERCEPT-Gerätefamilie unterstützt, gehen wir anschließend nacheinander durch:

  • Nehmt das Rohmuster und seht euch an, wie das Ereignis bei minimaler Verarbeitung und ohne Anwendung eines speziellen Log-Pfads in Splunk aussieht. 
  • Bestimmt in Rücksprache mit dem Anbieter und unter Einbeziehung der Splunk-App- bzw. TA-Dokumentation, ob die minimalen Felder, die in der ersten Syslog-Protokoll-Dekodierungsphase bereitgestellt werden, die Verwendung eines einfachen Log-Pfads erlauben oder ob ein herkömmlicher Log-Pfad entwickelt werden muss.
  • Falls ein einfacher Log-Pfad ausreicht, so konfiguriert ihr den eindeutigen Port und die Metadateneinträge entsprechend. Der Log-Pfad wird dann automatisch beim Start von SC4S erstellt.
  • Andernfalls erstellt ihr für das neue Gerät einen benutzerdefinierten Log-Pfad auf der Grundlage der bereitgestellten Beispielvorlage.

Beginnen wir, indem wir uns das Rohbeispiel in Splunk ansehen (entweder den Output eines echten Geräts oder mit dem oben genannten echo-Befehl):

Wir senden das Ereignis an SC4S (leicht gekürzt):

echo "<37>`date +\"%b %d %H:%M:%S\"`"'.986 stealth-host
 StealthINTERCEPT - Authentication Auth failed -
 PolicyName="StealthDEFEND for AD" Domain="TDOMAIN"
 Server="TDOMAIN-DC" ServerAddress="10.2.8.55" Perpetrator="MarkB"
 ClientHost="AP34.TEST.COM" ClientAddress="10.2.8.55"
 TargetHost="TDOMAN-DC.TEST.COM" TargetHostIP="10.135.33.7"' >
 /dev/udp/sc4s.test.com/514

Hier ist das Ereignis in Splunk; ihr könnt sehen, dass RAWMSG aktiviert ist:

Ein paar Dinge fallen sofort auf:

  • Die Nachricht hat eine gültige -Zeichenfolge, einen Zeitstempel, und etwas, was wie der Hostname erscheint, im Header. Das deutet darauf hin, dass das Ereignis zumindest minimal RFC-konform ist. Das lässt sich durch Überprüfen der indizierten Felder in Splunk bestätigen: – dieses Ereignis ist tatsächlich RFC 3164-konform.
  • Es gibt noch ein weiteres Feld (syslog-ng-„Makro“) namens PROGRAM, das in einem Filter sehr nützlich sein könnte – oder vielleicht als der Sourcetyp für das Ereignis? Ein kurzer Blick in die Stealthbits-Dokumentation zeigt, dass dieses Feld tatsächlich variieren kann – es könnte also hilfreich sein, dem Ereignis einen Sourcetyp zuzuweisen. Eine kurze Prüfung des TAs zeigt, dass SC4S mehr als einen Sourcetyp liefern muss. Damit ist ein einfacher Log-Pfad ausgeschlossen, wir müssen einen herkömmlichen Log-Pfad entwickeln. Es geht also weiter:

Log-Pfad-Entwicklung – Schritt für Schritt

Nun wissen wir, dass wir einen herkömmlichen Log-Pfad entwickeln müssen. Aber wo fangen wir an? Erinnert euch an die oben skizzierte Verzeichnisstruktur. Ihr seht dieses Verzeichnis:

/opt/sc4s/local/config/log-paths

There, you will see two files:

lp-example.conf
lp-example.conf.tmpl

Im Log-Pfad-Verzeichnis (und in den anderen Verzeichnissen im Verzeichnis „config“) liegen „reale“ syslog-ng-Konfigurationsdateien, die Teil der Gesamtkonfiguration sind, wenn Container (und der zugrunde liegende syslog-ng-Prozess) ausgeführt werden. Daher muss die Syntax fehlerfrei sein, sonst lässt sich das ganze Konstrukt gar nicht starten. Das ist der Grund, warum viele der .conf-Dateien nicht direkt bearbeitet werden, sondern über ihre .tmpl-Varianten. Über die in Teil 3 erörterten Variablenersetzungen und bedingten Ersetzungen hinaus ermöglicht es uns der Templating-Prozess, komplexe Teile des Log-Pfads zu abstrahieren, die vom Administrator nicht verfügbar gemacht (und nicht bearbeitet) werden müssen. Sehen wir uns zunächst die Datei lp-example.conf.tmpl an. Es braucht euch nicht zu kümmern, wenn die spezifische Beispieldatei in eurer speziellen SC4S-Version von der abweicht, die wir für diese Screenshots verwendet haben. Die Beispieldatei wird regelmäßig geändert, wenn SC4S verbessert und erweitert wird; zu dem Zeitpunkt, da ihr dies lest, wird es sicherlich Änderungen gegeben haben, die die Struktur einfacher machen. Haltet euch, wenn ihr im Folgenden die einzelnen Schritte durchgeht, an die Gesamtstruktur – sie bleibt konstant, unabhängig von den Besonderheiten der Datei.

Ihr werdet zuerst einmal feststellen, dass die Datei geradezu übermäßig mit Anweisungen auskommentiert ist. Die Anzahl der ausführbaren Zeilen, die übrig bleibt, ist tatsächlich recht klein. Zweitens ist ein kontextfähiger Text-Editor (wie Sublime im C-Sprachmodus) beim Erstellen eurer Vorlagendatei aus der Beispieldatei oben hilfreich, weil er die Syntaxprüfung erleichtert, auch wenn ihr vermutlich keinen auf eurem SC4S-Server verfügbar habt. Gehen wir nun die Schritte durch, die erforderlich sind, um diese „example“-Datei in einen Log-Pfad zu verwandeln, der mit einem echten Gerät funktioniert, in unserem Beispiel mit dem Stealthbits-Modell. Die folgenden Schritte bereiten den neuen Log-Pfad für die gerätespezifische Anpassung vor:

  1. Das Erste, was zu tun ist (und das ist wirklich wichtig): Kopiert die Beispieldatei in eine Vorlagendatei mit einem neuen Namen, die ihr dann für euren Log-Pfad verwendet (z. B. lp-stealthbits.conf.tmpl). Bearbeitet die Beispieldatei nicht direkt!
  2. Beachtet den Unterschied zwischen gomplate-Kommentaren (vorlagenbezogen) und normalen syslog-ng-Kommentaren (die herkömmliche Hashtags im Bash-Stil aufweisen). In den meisten Fällen werdet ihr die syslog-ng-Kommentare beibehalten, während die vorlagenbezogenen Kommentare nur selten genutzt werden.
  3. Der erste Abschnitt (Zeilen 1–26) ist größtenteils ein Kommentarblock mit Anweisungen, der sich auf einen wichtigen Aspekt der Verwendung der Beispieldatei konzentriert: Schlüsselausdrücke (z. B. LOCAL_EXAMPLE) in dieser Datei werden durch einen Ausdruck ersetzt, der den Anbieter und das Produkt darstellt, für das wir uns interessieren. In Übereinstimmung mit der überall in SC4S verwendeten „anbieter_produkt“-Konvention verwenden wir den Ausdruck STEALTHBITS_INTERCEPT.
  4. Ersetzt analog dazu alle Versionen derselben Zeichenfolge, die Kleinschreibung aufweisen (local_example), durch stealthbits_intercept.

Nach diesen String-Ersetzungen sehen wir uns nun die einzelnen Abschnitte der Reihe nach an. Wenn ihr die Codeausschnitte in den folgenden Snippets genau betrachtet, erkennt ihr die Zeichenfolgenersetzungen gegenüber dem vollständigen Screenshot der unveränderten Beispieldatei oben. Unserem geplanten Vorgehen entsprechend zerlegen wir diese Datei in vier Hauptabschnitte:

  • Quelle
  • Filter
  • Parsing/Metadaten
  • Ziel

Quelle

Beginnen wir mit dem Quellen-Teil des Log-Pfads. Ab Zeile 28 sehen wir dieses:

Diese beiden aus der Vorlage stammenden Codezeilen nehmen euch die meiste Arbeit ab, dank dem Vorlagenprozess. Alles, was ihr braucht, um eine benutzerdefinierte Quelldeklaration für euer Gerät zu erstellen, ist der Haupt-String STEALTHBITS_INTERCEPT, der den Stamm der Umgebungsvariablen darstellt, die zum Festlegen eindeutiger Listening-Ports verwendet werden, und ein Parser-Wert (der passend zur allgemeinen Struktur der Ereignisse festgelegt ist – wenn ihr unsicher seid, könnt ihr „common“ verwenden). Denkt daran, dass dieser Abschnitt die Quelldeklaration erstellen wird, d. h. die Funktion, die aus dem Log-Pfad aufgerufen wird, wie wir weiter unten noch sehen werden.

Filter

Als Nächstes untersuchen wir den Anfang des eigentlichen Log-Pfads, der in Zeile 32 beginnt (Zeile 34 ist abgeschnitten):

Ihr seht, dass jedes Ereignis zwei parallele Pfade durch einen Filter-Knotenpunkt („junction“) nimmt, die dann nach der Durchquerung aller „channel“-Elemente zusammengeführt werden. Im oberen Kanal wird die neu erstellte Quelle s_STEALTHBITS_INTERCEPT überprüft. Wenn an dieser Quelle (diesem eindeutigen Port) Ereignisse ankommen, werden sie ohne weitere Filterung an den restlichen Log-Pfad übergeben. Wenn das Element hingegen über den Standardport s_DEFAULT ankommt (normalerweise UDP oder TCP 514), könnt ihr sehen, dass es einen zusätzlichen Filter gibt (f_stealthbits_intercept), der ebenfalls passen muss, sonst wird das Ereignis nicht zu diesem Log-Pfad „durchgelassen“. Dieser Filter kann (ebenso wie die benutzerdefinierte Quelle) unmittelbar oberhalb des Abschnitts Log{} in der Log-Pfad-Datei deklariert oder in eine separate Datei ausgelagert werden (siehe unten). Wie die Quelle ist es lediglich eine Funktion, mit dem Namen f_stealthbits_intercept:

Werft einen Blick auf die Zeilen 2 und 3 und vergegenwärtigt euch den Screenshot der Rohnachricht in Splunk mit dem Feld PROGRAM. Dies ist ein Beispiel dafür, wie extrem nützlich der anfängliche Parsing-Durchgang beim Erstellen von Filtern in Log-Pfaden sein kann. Die Zeilen 2 und 3 zeigen, wie dieses Feld (bzw. „Makro“ in der syslog-ng-Terminologie) überprüft wird, ob es mit den beiden gezeigten Werten übereinstimmt. Im folgenden Abschnitt werdet ihr sehen, dass das gleiche Makro auch bei der Zuweisung von Sourcetypen – die das TA erwartet – sehr hilfreich sein kann.

Parsing/Metadaten

In dieser Phase der Entwicklung kann die gesamte Bandbreite der syslog-ng-Konfigurationsprogrammiersprache zum Zuge kommen. Ihr könnt zwar die komplette Ereignis-Nutzlast ausgiebig parsen und sogar bis zur vollständigen Feldextraktion im Stil von Splunk gehen, aber es ist am besten, wenn ihr das Parsen auf die Splunk-Metadaten beschränkt, die zusammen mit dem zu indizierenden Ereignis gesendet werden müssen. Diese Metadaten umfassen den normalen Index, die Uhrzeit, den Host, die Quelle und den Sourcetyp. Beachtet, dass die Uhrzeit in dieser Liste enthalten ist: Wir wollen sicherstellen, dass sie richtig geparst wird, bevor sie an Splunk gesendet wird, da die Zeitstempelverarbeitung (standardmäßig) mit dem von SC4S verwendeten /event-HEC-Endpunkt umgangen wird.

Hier ist das „Innenleben“ des Log-Pfads, in dem diese Metadaten-Zuweisung erfolgt:

Wie zu sehen ist, werden dem Entwickler mehrere Rewrite-Funktionen zur Verfügung gestellt, so dass man auch diesen Abschnitt für die meisten Log-Pfade quasi als Plug-and-play nutzen kann. Die Voreinstellungen für alle Splunk-Metadaten werden mit den Rewrites in den Zeilen 56 und 61 festgelegt – und welcher Rewrite verwendet wird, hängt vom Wert des Makros PROGRAM ab. Auch hier wurde das anfängliche syslog-ng-Parsing gut genutzt. Ihr könnt sehen, dass der Sourcetyp festgelegt wird, wenn diese Funktionen aufgerufen werden, jedoch keine der anderen Metadaten. Dies liegt daran, dass die anderen Metadaten (Host, Uhrzeit und Quelle) normalerweise zum Zeitpunkt des Einlesens (in der Quelldeklaration) festgelegt werden und hier nicht explizit bestimmt (oder überschrieben) werden müssen.

Aber was ist mit dem Index? Da wollen wir normalerweise keinen Standardwert verwenden, also wo wird er festgelegt? Das geschieht in Zeile 66 – das ist der Parser, der auf die Datei splunk_metadata.csv zugreift, wie in Teil3 dieser Blog-Serie erörtert. Das einzige Argument, das in diese Funktion übergeben wird, ist der Schlüssel, den der Entwickler zuweist (wiederum unter Verwendung der anbieter_produkt-Konvention). In ähnlicher Weise wird auf die Dateien compliance_meta_by_source.* im Parser verwiesen, der in Zeile 70 aufgerufen wird. Dies ist der letzte Lookup, der berücksichtigt wird, bevor das Ereignis an ein oder mehrere Ziele gesendet wird. Dazu kommen wir jetzt.

Ziel

Nach der Festlegung aller Variablen (einschließlich verschiedener indizierter Felder, die aus dem anfänglichen syslog-ng-Parsing bezogen sind) ist das Ereignis bereit, an ein oder mehrere Ziele gesendet zu werden. Diese Ziele werden stark von Umgebungsvariablen gesteuert, was wiederum mehrere Vorlagenkonstrukte bedeutet. Dieser Abschnitt der Datei sieht so aus:

Der letzte Schritt vor dem Senden ist das Festlegen der Output-Vorlage, was in Zeile 75 zu sehen ist. Dazu wird eine geeignete Standardvorlage gewählt (die weitgehend auf dem basiert, was das TA erwartet). Diese Vorlagen sind alle dokumentiert und aus den verschiedenen syslog-ng-Makros aufgebaut (PROGRAM, MESSAGE usw.). Diese Vorgabe kann man auf Wunsch mithilfe von splunk_metadata.csv außer Kraft setzen. Schließlich werden in den Zeilen 81 bis 102 Umgebungsvariablen berücksichtigt und entsprechende Ziele zur endgültigen Konfigurationsdatei hinzugefügt. Der Log-Pfad endet dann mit zwei Flags – einem, das syslog-ng anweist, TCP-Datenverkehr bei Bedarf einer Ablaufsteuerung zu unterwerfen (bei UDP ist das nicht möglich), und einem, das bewirkt, dass das Ergebnis in keinen anderen Log-Pfad gelangt und die Verarbeitung beendet wird.

Endgültige Ausgabe

Und wie sieht das alles aus, wenn die Vorlagendatei durch die gomplate-Templating-Engine geht? Hier ist die Ausgabe nach der Vorlagenverarbeitung unseres Beispiels, wobei die Variablen

SC4S_LISTEN_STEALTHBITS_INTERCEPT_TCP_PORT=5015
SC4S_DEST_GLOBAL_ALTERNATES=d_hec_debug

set in the env_file:

Als Erstes werdet ihr bemerken, dass der gomplate-Code mit den geschweiften Klammern jetzt komplett verschwunden ist. Die Datei beginnt mit der Quelldeklaration (das sind lediglich drei Zeilen gomplate-Code) und hat sich in der endgültigen Ausgabe auf mehrere Zeilen (11–48) ausgeweitet. Die Quelldeklaration besorgt einen großen Teil der anfänglichen Metadaten, die Vorbereitung der indizierten Felder sowie die Einrichtung des Listening-Sockets an TCP-Port 5015 gemäß der Einstellung in der env_file. Die Abschnitte für Filterung und Parsing (Zeilen 50–87) durchlaufen die Templating-Engine relativ unverändert, während der Zielabschnitt (der aus mehreren Zeilen gomplate-Code bestand) in der endgültigen Ausgabe letztlich auf drei Codezeilen reduziert ist (Zeilen 91–93) und das Ziel d_hec_debug enthält, wiederum aufgrund der Einstellung in der env_file.

Log-Pfad-Entwicklung – das Ergebnis in Splunk

Hier ist das Endergebnis, wie es in Splunk erscheint. Beachtet, dass das Ausgabeformat nicht mehr JSON ist (wie das bei „Reserve“-Ereignissen der Fall ist), sondern einfach das ursprünglicher Ereignis ohne den Header (-Zeichenfolge, Host und Zeitstempel). Das ist es, was die meisten TAs erwarten.

Hier noch ein paar praktische Tipps für die Entwicklung:

  • Stellt sicher, dass ihr das Quellgerät (oder die Erfassungslogs) in dem Format konfiguriert, das Anbieter und/oder TA-Autor empfehlen. Dies ist ein kritischer Punkt, und zwar noch bevor ihr mit den Entwicklungsarbeiten beginnt, denn es wird sich sehr wahrscheinlich schon auf das frühe Parsen des Syslog-Protokolls auswirken. Darüber hinaus sollten die Einstellungen auf dem Quellgerät im relevanten SC4S-Quelldokument (bei Übernahme als unterstützte Quelle) dokumentiert werden.
  • Wenn ihr vorhabt, Log-Pfade für mehrere benutzerdefinierte Quellen zu schreiben und damit einen Beitrag für die Community leisten wollt, dann zieht die Verwendung einer voll ausgestatteten IDE mit der pytest-Suite in Betracht, die auf GitHub zur Verfügung steht. Es ist gute Praxis, den Test vor dem Code zu schreiben, damit ihr wisst, ob euer Log-Pfad funktional korrekt ist und dass er keine Auswirkungen auf den Rest der Codebasis hat.
  • Testet euren neuen Log-Pfad so früh wie möglich. Testet bereits nach dem einfachen Ersetzen der anfänglichen LOCAL_EXAMPLE-Zeichenfolgen und dem Erstellen eures Filters mit ein paar Ereignissen, damit ihr seht, ob der Log-Pfad eingeschlagen wird und mindestens ein Sourcetyp zugewiesen wird.
  • Zum Senden eines Rohereignisses an SC4S führt diesen einfachen Befehl an einer beliebigen Linux-Eingabeaufforderung aus:
    echo "<raw event text>" > /dev/udp/<sc4s host IP or name>/514
    • Dass ihr ein Rohereignis habt, ist entscheidend; der gesamte Log-Pfad und die gesamte Filterung hängen davon ab, dass es korrekt ist. Stellt keine Vermutungen an, sondern erfasst das Ereignis von einem realen Gerät!
  • Wenn sich die Entwicklung auf wenige Details beschränkt, ist es oftmals hilfreich, „exec in“ im Container auszuführen und „HUP“ an den syslog-Prozess auszugeben, damit ihr die Auswirkungen eurer Änderungen seht. In diesem Fall (und nur in diesem Fall) bearbeitet ihr conf-Dateien direkt und holt die Änderungen zurück in die tmpl-Dateien, wenn ihr zufrieden seid. Durch „exec in“ im Container bekommt ihr außerdem Einblick, wie die unterstützten Log-Pfade aussehen. Da lässt sich eine Menge tolles Material finden, das ihr für eure eigenen Log-Pfade kopieren könnt, Datumsparser, CSV-/kv-Parser usw., die sehr nützlich sein können.
  • Wenn ihr wisst, dass ihr etwas geändert habt, aber beim Start von SC4S nichts passiert, dann könnt ihr ziemlich sicher sein, dass ihr anstelle der tmpl-Datei die conf-Datei direkt bearbeitet habt. Nicht vergessen, conf-Dateien sind flüchtig und werden bei jedem Neustart neu erstellt!

Uns ist bewusst, dass dieser Beitrag die Entwicklungsdurchlauf im Sauseschritt ist und dass wir viele Details ausgelassen haben, insbesondere die Feinheiten der eigentlichen syslog-ng-Konfigurationssyntax. Die Community steht aber bereit, euch bei allen Fragen oder Entwurfsherausforderungen zu helfen. Viel Glück!


Splunk Connect for Syslog – Community

Splunk Connect for Syslog wird von Splunk voll unterstützt und ist als Open-Source-Projekt veröffentlicht. Wir hoffen auf eine engagierte Community, die uns mit Feedback, Verbesserungsvorschlägen, Kommunikation und vor allem der Erstellung von Log-Pfaden (Filtern) tatkräftig unterstützt! Für die aktive Teilnahme stellen wir die Git-Repos zur Verfügung, wo formelle Anfragen zur Aufnahme von Funktionen (insbesondere von Log-Pfaden/Filtern), Fehlerverfolgung usw. möglich sind. Wir gehen davon aus, dass es mit der Zeit deutlich weniger „lokale Filter“ geben wird, da immer mehr Beiträge der Community in den Out-of-the-box-Konfigurationen der Container gekapselt sein werden.

Splunk Connect for Syslog – Ressourcen

Es gibt eine ganze Menge von Ressourcen, die euch bei der erfolgreichen Nutzung von SC4S unterstützen! Neben dem Haupt-Repository und der Dokumentation gibt es zahlreiche weitere Informationsquellen, z.B. diese: