Übersicht über das Log-Parsing
In diesem Dokument finden Sie einen Überblick darüber, wie Google Security Operations Rohlogs in das Format des einheitlichen Datenmodells (UDM) parst.
Google SecOps kann Logdaten aus den folgenden Quellen für die Aufnahme empfangen:
- Google SecOps-Forwarder
- Chronicle API-Feed
- Chronicle Ingestion API
- Drittanbieter
In der Regel senden Kunden Daten als ursprüngliche Rohlogs. Google SecOps identifiziert das Gerät, das die Logs generiert hat, anhand des LogType. Der LogType identifiziert beides:
- Der Anbieter und das Gerät, von dem das Log generiert wurde, z. B. Cisco Firewall, Linux DHCP Server oder Bro DNS.
- Mit welchem Parser wird das Rohlog in ein strukturiertes UDM konvertiert? Zwischen einem Parser und einem LogType besteht eine 1:1-Beziehung. Jeder Parser konvertiert Daten, die von einem einzelnen LogType empfangen werden.
Google SecOps bietet eine Reihe von Standard-Parsern, die ursprüngliche Rohlogs lesen und strukturierte UDM-Datensätze anhand der Daten im ursprünglichen Rohlog generieren. Google SecOps verwaltet diese Parser. Kunden können auch benutzerdefinierte Anweisungen für die Datenzuordnung definieren, indem sie einen kundenspezifischen Parser erstellen.
Der Parser enthält Anweisungen zur Datenzuordnung. Sie definiert, wie Daten aus dem ursprünglichen Rohlog einem oder mehreren Feldern in der UDM-Datenstruktur zugeordnet werden.
Wenn keine Parsingfehler vorhanden sind, erstellt Google SecOps einen UDM-strukturierten Datensatz mit Daten aus dem Rohlog. Der Prozess der Umwandlung eines Rohlogs in einen UDM-Datensatz wird als Normalisierung bezeichnet.
Ein Standardparser kann eine Teilmenge von Kernwerten aus dem Rohlog zuordnen. In der Regel sind diese Kernfelder am wichtigsten, um Sicherheitsinformationen in Google SecOps bereitzustellen. Nicht zugeordnete Werte verbleiben im Rohlog, werden aber nicht im UDM-Datensatz gespeichert.
Ein Kunde kann auch die Ingestion API verwenden, um Daten im strukturierten UDM-Format zu senden.
Parsing von aufgenommenen Daten anpassen
Google SecOps bietet die folgenden Funktionen, mit denen Kunden das Parsen von Daten in eingehenden Original-Logdaten anpassen können.
- Kundenspezifische Parser: Kunden erstellen eine benutzerdefinierte Parserkonfiguration für einen bestimmten Logtyp, die ihren spezifischen Anforderungen entspricht. Ein kundenspezifischer Parser ersetzt den Standardparser für den jeweiligen LogType. Weitere Informationen finden Sie unter Vorgefertigte und benutzerdefinierte Parser verwalten.
- Parser-Erweiterungen: Kunden können zusätzlich zur Standard-Parserkonfiguration benutzerdefinierte Zuordnungsanweisungen hinzufügen. Jeder Kunde kann seine eigenen benutzerdefinierten Zuordnungsanweisungen erstellen. In dieser Zuordnungsanleitung wird beschrieben, wie zusätzliche Felder aus ursprünglichen Rohlogs in UDM-Felder extrahiert und transformiert werden. Eine Parsererweiterung ersetzt nicht den Standard- oder kundenspezifischen Parser.
Beispiel mit einem Squid-Webproxylog
In diesem Abschnitt finden Sie ein Beispiel für ein Squid-Webproxy-Log und eine Beschreibung, wie die Werte einem UDM-Datensatz zugeordnet werden. Eine Beschreibung aller Felder im UDM-Schema finden Sie in der Liste der Felder für einheitliche Datenmodelle (Unified Data Model, UDM).
Das Beispiel für das Squid-Webproxy-Log enthält durch Leerzeichen getrennte Werte. Jeder Datensatz steht für ein Ereignis und enthält die folgenden Daten: Zeitstempel, Dauer, Client, Ergebniscode/Ergebnisstatus, übertragene Byte, Anfragemethode, URL, Nutzer, Hierarchiecode und Inhaltstyp. In diesem Beispiel werden die folgenden Felder extrahiert und einem UDM-Datensatz zugeordnet: „time“, „client“, „result status“, „bytes“, „request method“ und „URL“.
1588059648.129 23 192.168.23.4 TCP_HIT/200 904 GET www.google.com/images/sunlogo.png - HIER_DIRECT/203.0.113.52 image/jpeg
Wenn Sie diese Strukturen vergleichen, werden Sie feststellen, dass nur ein Teil der ursprünglichen Logdaten im UDM-Datensatz enthalten ist. Einige Felder sind erforderlich, andere optional. Außerdem enthält nur eine Teilmenge der Abschnitte im UDM-Datensatz Daten. Wenn der Parser keine Daten aus dem ursprünglichen Log dem UDM-Datensatz zuordnet, wird dieser Abschnitt des UDM-Datensatzes in Google SecOps nicht angezeigt.
Im metadata
-Bereich wird der Ereignis-Zeitstempel gespeichert. Der Wert wurde vom EPOCH-Format ins RFC 3339-Format konvertiert. Diese Konvertierung ist optional. Der Zeitstempel kann im EPOCH-Format gespeichert werden. Dabei werden die Sekunden und Millisekunden in separate Felder aufgeteilt.
Im Feld metadata.event_type
wird der Wert NETWORK_HTTP
gespeichert. Das ist ein aufgezählter Wert, der den Ereignistyp angibt. Der Wert von metadata.event_type
bestimmt, welche zusätzlichen UDM-Felder erforderlich und welche optional sind. Die Werte product_name
und vendor_name
enthalten nutzerfreundliche Beschreibungen des Geräts, auf dem das ursprüngliche Log aufgezeichnet wurde.
Der metadata.event_type
in einem UDM-Ereignisdatensatz ist nicht derselbe wie der log_type, der beim Erfassen von Daten mit der Ingestion API definiert wird. In diesen beiden Attributen werden unterschiedliche Informationen gespeichert.
Der Bereich network
enthält Werte aus dem ursprünglichen Log-Ereignis. In diesem Beispiel wurde der Statuswert aus dem ursprünglichen Log aus dem Feld „result code/status“ geparst, bevor er in den UDM-Datensatz geschrieben wurde. Nur der result_code wurde in den UDM-Datensatz aufgenommen.
Im Abschnitt principal
werden die Clientinformationen aus dem ursprünglichen Log gespeichert. Im Abschnitt target
werden sowohl die vollständig qualifizierte URL als auch die IP-Adresse gespeichert.
Im Abschnitt security_result
wird einer der Enum-Werte gespeichert, der die im ursprünglichen Log aufgezeichnete Aktion darstellt.
Dies ist der als JSON formatierte UDM-Datensatz. Es werden nur Abschnitte mit Daten berücksichtigt. Die Abschnitte src
, observer
, intermediary
, about
und extensions
sind nicht enthalten.
{
"metadata": {
"event_timestamp": "2020-04-28T07:40:48.129Z",
"event_type": "NETWORK_HTTP",
"product_name": "Squid Proxy",
"vendor_name": "Squid"
},
"principal": {
"ip": "192.168.23.4"
},
"target": {
"url": "www.google.com/images/sunlogo.png",
"ip": "203.0.113.52"
},
"network": {
"http": {
"method": "GET",
"response_code": 200,
"received_bytes": 904
}
},
"security_result": {
"action": "UNKNOWN_ACTION"
}
}
Schritte in Parseranweisungen
Die Anweisungen zur Datenzuordnung in einem Parser folgen einem gemeinsamen Muster:
- Daten aus dem ursprünglichen Log parsen und extrahieren.
- Extrahierte Daten bearbeiten Dazu gehört, dass Sie mit bedingter Logik Werte selektiv parsen, Datentypen konvertieren, Teilstrings in einem Wert ersetzen, in Groß- oder Kleinbuchstaben konvertieren usw.
- UDM-Feldern Werte zuweisen
- Geben Sie den zugeordneten UDM-Datensatz über den Schlüssel @output aus.
Daten aus dem ursprünglichen Log parsen und extrahieren
Filteranweisung festlegen
Die filter
-Anweisung ist die erste Anweisung im Satz von Parsing-Anweisungen.
Alle zusätzlichen Parsing-Anweisungen sind in der filter
-Anweisung enthalten.
filter {
}
Variablen initialisieren, in denen extrahierte Werte gespeichert werden
Initialisieren Sie in der filter
-Anweisung Zwischenvariablen, in denen der Parser aus dem Log extrahierte Werte speichert.
Diese Variablen werden jedes Mal verwendet, wenn ein einzelner Log geparst wird. Der Wert in jeder Zwischenvariable wird später in den Parsing-Anweisungen auf ein oder mehrere UDM-Felder festgelegt.
mutate {
replace => {
"event.idm.read_only_udm.metadata.product_name" => "Webproxy"
"event.idm.read_only_udm.metadata.vendor_name" => "Squid"
"not_valid_log" => "false"
"when" => ""
"srcip" => ""
"action" => ""
"username" => ""
"url" => ""
"tgtip" => ""
"method" => ""
}
}
Einzelne Werte aus dem Log extrahieren
Google SecOps bietet eine Reihe von Filtern, die auf Logstash basieren, um Felder aus ursprünglichen Logdateien zu extrahieren. Je nach Format des Logs verwenden Sie einen oder mehrere Extraktionsfilter, um alle Daten aus dem Log zu extrahieren. Wenn der String so aussieht:
- natives JSON: Die Parser-Syntax ähnelt dem JSON-Filter, der JSON-formatierte Logs unterstützt. Verschachteltes JSON wird nicht unterstützt.
- Das XML-Format und die Parser-Syntax ähneln dem XML-Filter, der XML-formatierte Logs unterstützt.
- Schlüssel/Wert-Paare. Die Parser-Syntax ähnelt dem Kv-Filter, der Nachrichten im Schlüssel/Wert-Format unterstützt.
- CSV-Format, Parser-Syntax ähnelt dem CSV-Filter, der CSV-formatierte Nachrichten unterstützt.
- Bei allen anderen Formaten ähnelt die Parser-Syntax dem GROK-Filter mit integrierten GROK-Mustern . Hierbei werden Extraktionsanweisungen im Regex-Stil verwendet.
Google SecOps bietet eine Teilmenge der Funktionen, die in den einzelnen Filtern verfügbar sind. Google SecOps bietet auch eine benutzerdefinierte Syntax für die Datenzuordnung, die in den Filtern nicht verfügbar ist. Eine Beschreibung der unterstützten Funktionen und benutzerdefinierten Funktionen finden Sie in der Referenz zur Parser-Syntax.
Im Beispiel für das Squid-Webproxy-Log enthält die folgende Anweisung zum Extrahieren von Daten eine Kombination aus Logstash-Grok-Syntax und regulären Ausdrücken.
Mit der folgenden Extraktionsanweisung werden Werte in den folgenden Zwischenvariablen gespeichert:
when
srcip
action
returnCode
size
method
username
url
tgtip
In dieser Beispielanweisung wird auch das Keyword overwrite
verwendet, um die extrahierten Werte in den einzelnen Variablen zu speichern. Wenn beim Extrahieren ein Fehler auftritt, wird not_valid_log
durch die on_error
-Anweisung auf True
gesetzt.
grok {
match => {
"message" => [
"%{NUMBER:when}\\s+\\d+\\s%{SYSLOGHOST:srcip} %{WORD:action}\\/%{NUMBER:returnCode} %{NUMBER:size} %{WORD:method} (?P<url>\\S+) (?P<username>.*?) %{WORD}\\/(?P<tgtip>\\S+).*"
]
}
overwrite => ["when","srcip","action","returnCode","size","method","url","username","tgtip"]
on_error => "not_valid_log"
}
Extrahierte Werte bearbeiten und transformieren
Google SecOps nutzt die Funktionen des Logstash-Mutate-Filter-Plug-ins, um die aus dem ursprünglichen Log extrahierten Werte zu bearbeiten. Google SecOps bietet einen Teil der Funktionen, die im Plug-in verfügbar sind. Eine Beschreibung der unterstützten Funktionen und benutzerdefinierten Funktionen finden Sie unter Parser-Syntax, z. B.:
- Werte in einen anderen Datentyp umwandeln
- Werte im String ersetzen
- zwei Arrays zusammenführen oder einen String an ein Array anhängen. String-Werte werden vor dem Zusammenführen in ein Array konvertiert.
- in Klein- oder Großbuchstaben umwandeln
In diesem Abschnitt finden Sie Beispiele für die Datentransformation, die auf dem zuvor gezeigten Squid-Webproxy-Log basieren.
Ereigniszeitstempel transformieren
Alle Ereignisse, die als UDM-Datensatz gespeichert werden, müssen einen Ereigniszeitstempel haben. In diesem Beispiel wird geprüft, ob ein Wert für die Daten aus dem Log extrahiert wurde. Anschließend wird die Grok-Datumsfunktion verwendet, um den Wert mit dem Zeitformat UNIX
abzugleichen.
if [when] != "" {
date {
match => [
"when", "UNIX"
]
}
}
username
-Wert transformieren
Mit der folgenden Beispielanweisung wird der Wert in der Variablen username
in Kleinbuchstaben umgewandelt.
mutate {
lowercase => [ "username"]
}
action
-Wert transformieren
Im folgenden Beispiel wird der Wert in der Zwischenvariable action
ausgewertet und in ALLOW, BLOCK oder UNKNOWN_ACTION geändert. Das sind gültige Werte für das UDM-Feld security_result.action
. Das UDM-Feld security_result.action
ist ein Aufzählungstyp, in dem nur bestimmte Werte gespeichert werden.
if ([action] == "TCP_DENIED" or [action] == "TCP_MISS" or [action] == "Denied" or [action] == "denied" or [action] == "Dropped") {
mutate {
replace => {
"action" => "BLOCK"
}
}
} else if ([action] == "TCP_TUNNEL" or [action] == "Accessed" or [action] == "Built" or [action] == "Retrieved" or [action] == "Stored") {
mutate {
replace => {
"action" => "ALLOW"
}
}
} else {
mutate {
replace => {
"action" => "UNKNOWN_ACTION" }
}
}
Ziel-IP-Adresse transformieren
Im folgenden Beispiel wird nach einem Wert in der Zwischenvariablen tgtip
gesucht.
Wenn der Wert gefunden wird, wird er mithilfe eines vordefinierten Grok-Musters mit einem IP-Adressmuster abgeglichen. Wenn beim Abgleichen des Werts mit einem IP-Adressmuster ein Fehler auftritt, wird die Eigenschaft not_valid_tgtip
von der Funktion on_error
auf True
gesetzt. Wenn die Übereinstimmung erfolgreich ist, wird die Property not_valid_tgtip
nicht festgelegt.
if [tgtip] not in [ "","-" ] {
grok {
match => {
"tgtip" => [ "%{IP:tgtip}" ]
}
overwrite => ["tgtip"]
on_error => "not_valid_tgtip"
}
Datentyp von „returnCode“ und „size“ ändern
Im folgenden Beispiel wird der Wert in der Variablen size
in uinteger
und der Wert in der Variablen returnCode
in integer
umgewandelt. Das ist erforderlich, da die Variable size
im UDM-Feld network.received_bytes
gespeichert wird, in dem ein int64
-Datentyp gespeichert ist. Die Variable returnCode
wird im UDM-Feld network.http.response_code
gespeichert, in dem ein int32
-Datentyp gespeichert wird.
mutate {
convert => {
"returnCode" => "integer"
"size" => "uinteger"
}
}
UDM-Feldern in einem Ereignis Werte zuweisen
Nachdem Werte extrahiert und vorverarbeitet wurden, weisen Sie sie Feldern in einem UDM-Ereignisdatensatz zu. Sie können einem UDM-Feld sowohl extrahierte als auch statische Werte zuweisen.
Wenn Sie event.disambiguation_key
ausfüllen, muss dieses Feld für jedes Ereignis, das für das angegebene Log generiert wird, eindeutig sein. Wenn zwei verschiedene Ereignisse denselben disambiguation_key
-Wert haben, führt dies zu unerwartetem Verhalten im System.
Die Parserbeispiele in diesem Abschnitt bauen auf dem vorherigen Beispiel für Squid-Webproxylogs auf.
Zeitstempel des Ereignisses speichern
Für jeden UDM-Ereignisdatensatz muss ein Wert für das UDM-Feld metadata.event_timestamp
festgelegt sein. Im folgenden Beispiel wird der aus dem Log extrahierte Ereigniszeitstempel in der integrierten Variable @timestamp
gespeichert. In Google Security Operations wird dies standardmäßig im UDM-Feld metadata.event_timestamp
gespeichert.
mutate {
rename => {
"when" => "timestamp"
}
}
Ereignistyp festlegen
Für jeden UDM-Ereignisdatensatz muss ein Wert für das UDM-Feld metadata.event_type
festgelegt sein. Dieses Feld ist ein Aufzählungstyp. Der Wert dieses Felds bestimmt, welche zusätzlichen UDM-Felder ausgefüllt werden müssen, damit der UDM-Datensatz gespeichert werden kann.
Der Parsing- und Normalisierungsprozess schlägt fehl, wenn eines der erforderlichen Felder keine gültigen Daten enthält.
replace => {
"event.idm.read_only_udm.metadata.event_type" => "NETWORK_HTTP"
}
}
Speichern Sie die Werte username
und method
mit der replace
-Anweisung.
Die Werte in den Zwischenfeldern username
und method
sind Strings. Im folgenden Beispiel wird geprüft, ob ein gültiger Wert vorhanden ist. Wenn dies der Fall ist, wird der username
-Wert im UDM-Feld principal.user.userid
und der method
-Wert im UDM-Feld network.http.method
gespeichert.
if [username] not in [ "-" ,"" ] {
mutate {
replace => {
"event.idm.read_only_udm.principal.user.userid" => "%{username}"
}
}
}
if [method] != "" {
mutate {
replace => {
"event.idm.read_only_udm.network.http.method" => "%{method}"
}
}
}
Speichern Sie action
im UDM-Feld security_result.action
.
Im vorherigen Abschnitt wurde der Wert in der Zwischenvariable action
ausgewertet und in einen der Standardwerte für das UDM-Feld security_result.action
umgewandelt.
In den UDM-Feldern security_result
und action
wird ein Array mit Elementen gespeichert. Daher müssen Sie beim Speichern dieses Werts etwas anders vorgehen.
Speichern Sie den transformierten Wert zuerst in einem Zwischenfeld security_result.action
. Das Feld security_result
ist ein übergeordnetes Element des Felds action
.
mutate {
merge => {
"security_result.action" => "action"
}
}
Speichern Sie als Nächstes das Zwischenfeld security_result.action
im UDM-Feld security_result
. Im UDM-Feld security_result
wird ein Array mit Elementen gespeichert. Der Wert wird also an dieses Feld angehängt.
# save the security_result field
mutate {
merge => {
"event.idm.read_only_udm.security_result" => "security_result"
}
}
Speichern Sie die Ziel-IP-Adresse und die Quell-IP-Adresse mit der merge
-Anweisung.
Speichern Sie die folgenden Werte im UDM-Ereignisdatensatz:
- Wert der Zwischenvariablen
srcip
für das UDM-Feldprincipal.ip
. - Wert der Zwischenvariablen
tgtip
für das UDM-Feldtarget.ip
.
In den UDM-Feldern principal.ip
und target.ip
wird jeweils ein Array mit Elementen gespeichert. Daher werden Werte an jedes Feld angehängt.
Die folgenden Beispiele zeigen verschiedene Ansätze zum Speichern dieser Werte.
Während des Transformationsschritts wurde die Zwischenvariable tgtip
mithilfe eines vordefinierten Grok-Musters einer IP-Adresse zugeordnet. Mit der folgenden Beispielanweisung wird geprüft, ob das Attribut not_valid_tgtip
auf „true“ gesetzt ist. Das bedeutet, dass der tgtip
-Wert nicht mit einem IP-Adressmuster abgeglichen werden konnte. Ist der Wert „false“, wird der tgtip
-Wert im UDM-Feld target.ip
gespeichert.
if ![not_valid_tgtip] {
mutate {
merge => {
"event.idm.read_only_udm.target.ip" => "tgtip"
}
}
}
Die Zwischenvariable „srcip
“ wurde nicht transformiert. Mit der folgenden Anweisung wird geprüft, ob ein Wert aus dem ursprünglichen Log extrahiert wurde. Wenn dies der Fall ist, wird der Wert im UDM-Feld principal.ip
gespeichert.
if [srcip] != "" {
mutate {
merge => {
"event.idm.read_only_udm.principal.ip" => "srcip"
}
}
}
url
, returnCode
und size
mit der rename
-Anweisung speichern
Mit der folgenden Beispielanweisung werden die Werte mit der rename
-Anweisung gespeichert:
- Die Variable
url
wurde im UDM-Feldtarget.url
gespeichert. - Die Zwischenvariable
returnCode
wurde im UDM-Feldnetwork.http.response_code
gespeichert. - Die Zwischenvariable
size
wurde im UDM-Feldnetwork.received_bytes
gespeichert.
mutate {
rename => {
"url" => "event.idm.read_only_udm.target.url"
"returnCode" => "event.idm.read_only_udm.network.http.response_code"
"size" => "event.idm.read_only_udm.network.received_bytes"
}
}
UDM-Datensatz an die Ausgabe binden
Mit der letzten Anweisung in der Datenzuordnung werden die verarbeiteten Daten in einen UDM-Ereignisdatensatz ausgegeben.
mutate {
merge => {
"@output" => "event"
}
}
Der vollständige Parsercode
Hier ist das vollständige Beispiel für den Parsercode. Die Reihenfolge der Anweisungen entspricht nicht der Reihenfolge der vorherigen Abschnitte dieses Dokuments, führt aber zur gleichen Ausgabe.
filter {
# initialize variables
mutate {
replace => {
"event.idm.read_only_udm.metadata.product_name" => "Webproxy"
"event.idm.read_only_udm.metadata.vendor_name" => "Squid"
"not_valid_log" => "false"
"when" => ""
"srcip" => ""
"action" => ""
"username" => ""
"url" => ""
"tgtip" => ""
"method" => ""
}
}
# Extract fields from the raw log.
grok {
match => {
"message" => [
"%{NUMBER:when}\\s+\\d+\\s%{SYSLOGHOST:srcip} %{WORD:action}\\/%{NUMBER:returnCode} %{NUMBER:size} %{WORD:method} (?P<url>\\S+) (?P<username>.*?) %{WORD}\\/(?P<tgtip>\\S+).*"
]
}
overwrite => ["when","srcip","action","returnCode","size","method","url","username","tgtip"]
on_error => "not_valid_log"
}
# Parse event timestamp
if [when] != "" {
date {
match => [
"when", "UNIX"
]
}
}
# Save the value in "when" to the event timestamp
mutate {
rename => {
"when" => "timestamp"
}
}
# Transform and save username
if [username] not in [ "-" ,"" ] {
mutate {
lowercase => [ "username"]
}
}
mutate {
replace => {
"event.idm.read_only_udm.principal.user.userid" => "%{username}"
}
}
if ([action] == "TCP_DENIED" or [action] == "TCP_MISS" or [action] == "Denied" or [action] == "denied" or [action] == "Dropped") {
mutate {
replace => {
"action" => "BLOCK"
}
}
} else if ([action] == "TCP_TUNNEL" or [action] == "Accessed" or [action] == "Built" or [action] == "Retrieved" or [action] == "Stored") {
mutate {
replace => {
"action" => "ALLOW"
}
}
} else {
mutate {
replace => {
"action" => "UNKNOWN_ACTION" }
}
}
# save transformed value to an intermediary field
mutate {
merge => {
"security_result.action" => "action"
}
}
# save the security_result field
mutate {
merge => {
"event.idm.read_only_udm.security_result" => "security_result"
}
}
# check for presence of target ip. Extract and store target IP address.
if [tgtip] not in [ "","-" ] {
grok {
match => {
"tgtip" => [ "%{IP:tgtip}" ]
}
overwrite => ["tgtip"]
on_error => "not_valid_tgtip"
}
# store target IP address
if ![not_valid_tgtip] {
mutate {
merge => {
"event.idm.read_only_udm.target.ip" => "tgtip"
}
}
}
}
# convert the returnCode and size to integer data type
mutate {
convert => {
"returnCode" => "integer"
"size" => "uinteger"
}
}
# save url, returnCode, and size
mutate {
rename => {
"url" => "event.idm.read_only_udm.target.url"
"returnCode" => "event.idm.read_only_udm.network.http.response_code"
"size" => "event.idm.read_only_udm.network.received_bytes"
}
# set the event type to NETWORK_HTTP
replace => {
"event.idm.read_only_udm.metadata.event_type" => "NETWORK_HTTP"
}
}
# validate and set source IP address
if [srcip] != "" {
mutate {
merge => {
"event.idm.read_only_udm.principal.ip" => "srcip"
}
}
}
# save event to @output
mutate {
merge => {
"@output" => "event"
}
}
} #end of filter
Benötigen Sie weitere Hilfe? Antworten von Community-Mitgliedern und Google SecOps-Experten erhalten