Log-Parsing – Übersicht

Unterstützt in:

In diesem Dokument finden Sie einen Überblick darüber, wie Google Security Operations Rohlogs in das Unified Data Model (UDM)-Format parset.

Google Security Operations kann Protokolldaten aus den folgenden Aufnahmequellen empfangen:

  • Google Security Operations-Weiterleitung
  • Google Security Operations API-Feed
  • Google Security Operations Ingestion API
  • Technologiepartner

In der Regel senden Kunden Daten als ursprüngliche Rohprotokolle. Google Security Operations identifiziert das Gerät, auf dem die Protokolle generiert wurden, anhand des LogType eindeutig. Der LogType gibt Folgendes an:

  • den Anbieter und das Gerät, das das Protokoll generiert hat, z. B. Cisco-Firewall, Linux-DHCP-Server oder Bro-DNS.
  • Dieser Parser wandelt das Rohprotokoll in ein strukturiertes UDM um. Zwischen einem Parser und einem LogType besteht eine 1:1-Beziehung. Jeder Parser konvertiert Daten, die von einem einzelnen LogType empfangen wurden.

Google Security Operations bietet eine Reihe von Standardparsern, die ursprüngliche Rohlogs lesen und strukturierte UDM-Einträge mithilfe der Daten im ursprünglichen Rohlog generieren. Diese Parser werden von Google Security Operations verwaltet. Kunden können auch benutzerdefinierte Datenzuordnungsanweisungen definieren, indem sie einen kundenspezifischen Parser erstellen.

Workflow für Datenaufnahme und Normalisierung

Der Parser enthält Anweisungen zur Datenzuordnung. Sie definiert, wie Daten aus dem ursprünglichen Rohprotokoll einem oder mehreren Feldern in der UDM-Datenstruktur zugeordnet werden.

Wenn keine Fehler beim Parsen auftreten, erstellt Google Security Operations einen UDM-strukturierten Datensatz mit Daten aus dem Rohprotokoll. Die Umwandlung eines Rohlogs in einen UDM-Eintrag wird als Normalisierung bezeichnet.

Ein Standardparser kann eine Teilmenge der Hauptwerte aus dem Rohprotokoll zuordnen. In der Regel sind diese Hauptfelder am wichtigsten, um Sicherheitsinformationen in Google Security Operations bereitzustellen. Nicht zugeordnete Werte bleiben im Rohprotokoll, werden aber nicht im UDM-Eintrag gespeichert.

Kunden können auch die Ingestion API verwenden, um Daten im strukturierten UDM-Format zu senden.

Parsen von aufgenommenen Daten anpassen

Google Security Operations bietet die folgenden Funktionen, mit denen Kunden das Parsen von Daten bei eingehenden ursprünglichen Protokolldaten anpassen können.

  • Kundenspezifische Parser: Kunden erstellen eine benutzerdefinierte Parserkonfiguration für einen bestimmten Protokolltyp, der ihren spezifischen Anforderungen entspricht. Ein kundenspezifischer Parser ersetzt den Standardparser für den jeweiligen LogType. Weitere Informationen finden Sie unter Vordefinierte und benutzerdefinierte Parser verwalten.
  • Parsererweiterungen: Kunden können zusätzlich zur Standardparserkonfiguration benutzerdefinierte Zuordnungsanweisungen hinzufügen. Jeder Kunde kann seine eigenen benutzerdefinierten Zuordnungsanleitungen erstellen. In diesen Zuordnungsanweisungen wird beschrieben, wie zusätzliche Felder aus den ursprünglichen Rohprotokollen in UDM-Felder extrahiert und transformiert werden. Eine Parsererweiterung ersetzt nicht den standardmäßigen oder kundenspezifischen Parser.

Beispiel für ein Squid-Webproxy-Log

In diesem Abschnitt finden Sie ein Beispiel für ein Squid-Webproxy-Protokoll und eine Beschreibung, wie die Werte einem UDM-Eintrag zugeordnet werden. Eine Beschreibung aller Felder im UDM-Schema finden Sie unter Liste der Felder für einheitliche Datenmodelle.

Das Beispiel-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 Bytes, Anfragemethode, URL, Nutzer, Hierarchiecode und Inhaltstyp. In diesem Beispiel werden die folgenden Felder extrahiert und einem UDM-Eintrag zugeordnet: Zeit, Client, Ergebnisstatus, Byte, Anfragemethode 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

Beispiel für einen Squid-Webproxy

Beim Vergleich dieser Strukturen fällt auf, dass nur ein Teil der ursprünglichen Protokolldaten im UDM-Eintrag enthalten ist. Bestimmte Felder sind erforderlich, andere optional. Außerdem enthalten nur einige Abschnitte im UDM-Eintrag Daten. Wenn der Parser keine Daten aus dem ursprünglichen Protokoll dem UDM-Eintrag zuordnet, wird dieser Abschnitt des UDM-Eintrags in Google Security Operations nicht angezeigt.

Logwerte, die UDM zugeordnet sind

Im Bereich metadata wird der Zeitstempel des Ereignisses gespeichert. Der Wert wurde aus dem EPOCH-Format in das RFC 3339-Format konvertiert. Diese Umwandlung ist optional. Der Zeitstempel kann im EPOCH-Format gespeichert werden. Dabei werden die Sekunden und Millisekunden in separaten Feldern gespeichert.

Im Feld metadata.event_type ist der Wert NETWORK_HTTP gespeichert. Dies ist ein enumerierter Wert, der den Ereignistyp angibt. Anhand des Werts von metadata.event_type wird festgelegt, welche zusätzlichen UDM-Felder erforderlich oder optional sind. Die Werte product_name und vendor_name enthalten nutzerfreundliche Beschreibungen des Geräts, auf dem das ursprüngliche Protokoll aufgezeichnet wurde.

Der Wert für metadata.event_type in einem UDM-Ereignisdatensatz entspricht nicht dem „log_type“, der beim Aufnehmen von Daten mit der Ingestion API definiert wurde. In diesen beiden Attributen werden unterschiedliche Informationen gespeichert.

Der Bereich network enthält Werte aus dem ursprünglichen Protokollereignis. In diesem Beispiel wurde der Statuswert aus dem ursprünglichen Protokoll aus dem Feld „result_code/status“ geparst, bevor er in den UDM-Eintrag geschrieben wurde. Nur der „result_code“ wurde in den UDM-Eintrag aufgenommen.

Logwerte, die UDM zugeordnet sind

Im Abschnitt principal werden die Clientinformationen aus dem ursprünglichen Protokoll 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 Aktion darstellt, die im ursprünglichen Protokoll aufgezeichnet wurde.

Das ist der UDM-Eintrag im JSON-Format. Es werden nur Abschnitte berücksichtigt, die Daten enthalten. 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 Parseranleitungen

Anweisungen zur Datenzuordnung in einem Parser folgen einem gängigen Muster:

  1. Daten aus dem ursprünglichen Protokoll analysieren und extrahieren.
  2. Die extrahierten Daten bearbeiten. Dazu gehört beispielsweise die Verwendung bedingter Logik, um Werte selektiv zu analysieren, Datentypen zu konvertieren, Teilstrings in einem Wert zu ersetzen oder in Groß- oder Kleinbuchstaben umzuwandeln.
  3. Weisen Sie UDM-Feldern Werte zu.
  4. Gib den zugeordneten UDM-Eintrag mit dem Schlüssel „@output“ aus.

Daten aus dem ursprünglichen Protokoll parsen und extrahieren

Filteranweisung festlegen

Die filter-Anweisung ist die erste Anweisung in den Parseanweisungen. Alle zusätzlichen Parseanweisungen sind in der filter-Anweisung enthalten.

filter {

}

Variablen initialisieren, in denen extrahierte Werte gespeichert werden

Innerhalb der filter-Anweisung müssen Sie Zwischenvariablen initialisieren, in denen der Parser die aus dem Protokoll extrahierten Werte speichert.

Diese Variablen werden jedes Mal verwendet, wenn ein einzelnes Protokoll geparst wird. Der Wert in jeder Zwischenvariablen wird später in den Parseanweisungen 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 Protokoll extrahieren

Google Security Operations bietet eine Reihe von Filtern auf der Grundlage von Logstash, mit denen Felder aus ursprünglichen Protokolldateien extrahiert werden können. Je nach Format des Logs verwenden Sie einen oder mehrere Extrahierungsfilter, um alle Daten aus dem Log zu extrahieren. Wenn der String:

  • Natives JSON: Die Parsersyntax ähnelt dem JSON-Filter, der JSON-formatierte Protokolle unterstützt. Verschachtelte JSON-Objekte werden nicht unterstützt.
  • XML-Format, Parsersyntax ähnelt dem XML-Filter, der Protokolle im XML-Format unterstützt.
  • Schlüssel/Wert-Paare, die Parsersyntax ähnelt dem Kv-Filter, der Nachrichten im Schlüssel/Wert-Format unterstützt.
  • CSV-Format, die Parsersyntax ähnelt dem CSV-Filter, der Nachrichten im CSV-Format unterstützt.
  • Bei allen anderen Formaten ähnelt die Parsersyntax dem GROK-Filter mit eingebauten GRK-Mustern . Dabei werden Regex-basierte Extraktionsanweisungen verwendet.

Google Security Operations bietet einen Teil der Funktionen, die in den einzelnen Filtern verfügbar sind. Google Security Operations bietet außerdem eine benutzerdefinierte Syntax für den Datenabgleich, die in den Filtern nicht verfügbar ist. Eine Beschreibung der unterstützten Funktionen und benutzerdefinierten Funktionen finden Sie in der Referenz zur Parsersyntax.

Anknüpfend an das Beispiel für das Squid-Webproxy-Log enthält die folgende Anweisung zur Datenextraktion eine Kombination aus Logstash-Grok-Syntax und regulären Ausdrücken.

In 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 der Extraktionsprozess einen Fehler zurückgibt, wird durch die on_error-Anweisung not_valid_log 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"
}

Die extrahierten Werte bearbeiten und transformieren

Google Security Operations nutzt die Funktionen des Logstash-Plug-ins „mutate“, um Werte zu manipulieren, die aus dem ursprünglichen Protokoll extrahiert wurden. Google Security Operations bietet einen Teil der Funktionen, die im Plug-in verfügbar sind. Eine Beschreibung der unterstützten Funktionen und benutzerdefinierten Funktionen finden Sie in der Parsersyntax. Beispiele:

  • Werte in einen anderen Datentyp umwandeln
  • Werte im String ersetzen
  • zwei Arrays zusammenführen oder einem Array einen String anhängen. Stringwerte werden vor dem Zusammenführen in ein Array konvertiert.
  • in Klein- oder Großbuchstaben umwandeln

In diesem Abschnitt finden Sie Beispiele für Datentransformationen, die auf dem zuvor vorgestellten Squid-Webproxy-Log basieren.

Zeitstempel des Ereignisses transformieren

Alle als UDM-Datensatz gespeicherten Ereignisse müssen einen Ereigniszeitstempel haben. In diesem Beispiel wird geprüft, ob ein Wert für die Daten aus dem Protokoll extrahiert wurde. Anschließend wird der Wert mithilfe der Grok-Datumsfunktion dem Zeitformat UNIX zugeordnet.

if [when] != "" {
  date {
    match => [
      "when", "UNIX"
    ]
   }
 }

Wert für username transformieren

In der folgenden Beispielanweisung wird der Wert in der Variablen username in Kleinbuchstaben umgewandelt.

mutate {
   lowercase => [ "username"]
   }

Wert für action transformieren

Im folgenden Beispiel wird der Wert in der Zwischenvariablen action ausgewertet und in ALLOW, BLOCK oder UNKNOWN_ACTION geändert. Dies sind gültige Werte für das UDM-Feld security_result.action. Das UDM-Feld security_result.action ist ein enumerierter Typ, 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 in der Zwischenvariablen tgtip nach einem Wert gesucht. Wenn ein Wert gefunden wird, wird er mit einem IP-Adressmuster verglichen, das mit einem vordefinierten Grok-Muster erstellt wurde. Wenn beim Abgleich des Werts mit einem IP-Adressmuster ein Fehler auftritt, wird die Property not_valid_tgtip von der Funktion on_error auf True festgelegt. Wenn die Übereinstimmung erfolgreich war, 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 wird. 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 die 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 Protokoll generiert wird, eindeutig sein. Wenn zwei verschiedene Ereignisse dieselbe disambiguation_key haben, führt dies zu unerwartetem Verhalten im System.

Die Parserbeispiele in diesem Abschnitt bauen auf dem vorherigen Beispiel für Squid-Webproxy-Protokolle auf.

Zeitstempel des Ereignisses speichern

Für jeden UDM-Ereignisabsatz muss ein Wert für das UDM-Feld metadata.event_timestamp festgelegt sein. Im folgenden Beispiel wird der aus dem Protokoll extrahierte Ereigniszeitstempel in der vordefinierten Variablen @timestamp gespeichert. In Google Security Operations wird dieser Wert 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 enumerierter Typ. Anhand des Werts dieses Felds wird festgelegt, welche zusätzlichen UDM-Felder ausgefüllt werden müssen, damit der UDM-Eintrag gespeichert werden kann. Das Parsen und Normalisieren schlägt fehl, wenn eines der Pflichtfelder keine gültigen Daten enthält.

replace => {
    "event.idm.read_only_udm.metadata.event_type" => "NETWORK_HTTP"
   }
}

Werte für username und method mit der replace-Anweisung speichern

Die Werte in den Zwischenfeldern username und method sind Strings. Im folgenden Beispiel wird geprüft, ob ein gültiger Wert vorhanden ist. Ist das der Fall, wird der Wert username im UDM-Feld principal.user.userid und der Wert method 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}"
    }
  }
}

action im UDM-Feld security_result.action speichern

Im vorherigen Abschnitt wurde der Wert in der Zwischenvariablen action ausgewertet und in einen der Standardwerte für das UDM-Feld security_result.action umgewandelt.

Sowohl im UDM-Feld security_result als auch im UDM-Feld action wird ein Array von Elementen gespeichert. Das bedeutet, dass Sie beim Speichern dieses Werts einen etwas anderen Ansatz verfolgen müssen.

Speichern Sie den transformierten Wert zuerst in einem Zwischenfeld vom Typ security_result.action. Das Feld security_result ist ein übergeordnetes Feld des Felds action.

mutate {
   merge => {
     "security_result.action" => "action"
   }
}

Speichern Sie als Nächstes das Zwischenfeld security_result.action im UDM-Feld security_result. Das UDM-Feld security_result speichert ein Array von Elementen. Der Wert wird diesem Feld angehängt.

 # save the security_result field
mutate {
  merge => {
    "event.idm.read_only_udm.security_result" => "security_result"
  }
}

Speichern Sie die Ziel- und Quell-IP-Adresse mit der merge-Anweisung.

Speichere die folgenden Werte im UDM-Ereignisabzug:

  • Wert in der Zwischenvariablen srcip in das UDM-Feld principal.ip.
  • Wert in der Zwischenvariablen tgtip in das UDM-Feld target.ip.

Sowohl das UDM-Feld principal.ip als auch target.ip speichern ein Array von Elementen. Daher werden jedem Feld Werte 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 mit einer IP-Adresse abgeglichen. In der folgenden Beispielanweisung wird geprüft, ob für die Eigenschaft not_valid_tgtip der Wert „wahr“ festgelegt ist, was bedeutet, dass der Wert tgtip nicht mit einem IP‑Adressmuster abgeglichen werden konnte. Ist der Wert „false“, wird der Wert tgtip 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 Protokoll extrahiert wurde. Ist das der Fall, 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

In der folgenden Beispielanweisung werden die Werte mit der rename-Anweisung gespeichert:

  • Die Variable url, die im UDM-Feld target.url gespeichert ist.
  • Die Zwischenvariable returnCode, die im UDM-Feld network.http.response_code gespeichert ist.
  • Die Zwischenvariable size, die im UDM-Feld network.received_bytes gespeichert ist.
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-Eintrag an die Ausgabe binden

Die letzte Anweisung in der Datenzuordnungsanleitung gibt die verarbeiteten Daten in einem UDM-Ereignisdatensatz aus.

mutate {
    merge => {
      "@output" => "event"
    }
  }

Der vollständige Parsercode

Dies ist der vollständige Parsercode. Die Reihenfolge der Anweisungen entspricht nicht der Reihenfolge in den vorherigen Abschnitten dieses Dokuments, führt aber zum selben Ergebnis.

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