Google App Engine-Logs erfassen

Parserversion:3.0

Unterstützt in:

In diesem Dokument wird beschrieben, wie Sie Google App Engine-Logs mit Google Cloud Storage V2 in Google Security Operations aufnehmen.

Google App Engine ist eine vollständig verwaltete, serverlose Plattform zum Erstellen und Bereitstellen von Webanwendungen und APIs. App Engine generiert automatisch Anfragelogs für HTTP-Anfragen und Anwendungslogs aus Ihrem Code. Diese Logs werden an Cloud Logging gesendet und können zur Aufnahme in Google Security Operations in Cloud Storage exportiert werden.

Hinweis

Prüfen Sie, ob die folgenden Voraussetzungen erfüllt sind:

  • Eine Google SecOps-Instanz
  • Ein GCP-Projekt mit aktivierter Cloud Storage API
  • Berechtigungen zum Erstellen und Verwalten von GCS-Buckets
  • Berechtigungen zum Verwalten von IAM-Richtlinien für GCS-Buckets
  • Berechtigungen zum Erstellen von Cloud Logging-Senken (roles/logging.configWriter)
  • Eine aktive App Engine-Anwendung (Standard- oder flexible Umgebung)

Google Cloud Storage-Bucket erstellen

  1. Gehen Sie zur Google Cloud Console.
  2. Wählen Sie Ihr Projekt aus oder erstellen Sie ein neues.
  3. Rufen Sie im Navigationsmenü Cloud Storage > Buckets auf.
  4. Klicken Sie auf Bucket erstellen.
  5. Geben Sie die folgenden Konfigurationsdetails an:

    Einstellung Wert
    Bucket benennen Geben Sie einen global eindeutigen Namen ein, z. B. appengine-logs-export.
    Standorttyp Wählen Sie die Option aus, die am besten zu Ihren Anforderungen passt (Region, Dual-Region, Multi-Region).
    Standort Wählen Sie den Ort aus, z. B. us-central1.
    Speicherklasse Standard (empfohlen für Logs, auf die häufig zugegriffen wird)
    Zugriffskontrolle Einheitlich (empfohlen)
    Schutzmaßnahmen Optional: Objektversionsverwaltung oder Aufbewahrungsrichtlinie aktivieren
  6. Klicken Sie auf Erstellen.

Cloud Logging so konfigurieren, dass App Engine-Logs in GCS exportiert werden

Cloud Logging verwendet Logsenken, um Logeinträge an unterstützte Ziele weiterzuleiten, einschließlich Cloud Storage-Buckets. Die Identität des Autors der Senke erfordert die Rolle „Storage-Objekt-Ersteller“ (roles/storage.objectCreator) für den Ziel-Bucket.

Cloud Logging-Senke erstellen

  1. Rufen Sie in der Google Cloud Console Logging > Log Router auf.
  2. Klicken Sie auf Senke erstellen.
  3. Geben Sie die folgenden Konfigurationsdetails an:
    • Name der Senke: Geben Sie einen aussagekräftigen Namen ein, z. B. appengine-to-gcs.
    • Senkenbeschreibung: Optionale Beschreibung.
  4. Klicken Sie auf Weiter.
  5. Gehen Sie im Bereich Senkendienst auswählen so vor:
    • Senkendienst: Wählen Sie Cloud Storage-Bucket aus.
    • Cloud Storage-Bucket auswählen: Wählen Sie appengine-logs-export aus dem Drop-down-Menü aus.
  6. Klicken Sie auf Weiter.
  7. Geben Sie im Abschnitt Logs auswählen, die in der Senke enthalten sind eine Filterabfrage ein, um App Engine-Logs auszuwählen. Der Ressourcentyp muss genau „gae_app“ sein.

    Für alle App Engine-Logs (Anfrage- und Anwendungslogs) gilt:

    resource.type="gae_app"
    

    Nur für App Engine-Anfragelogs:

    resource.type="gae_app"
    logName="projects/PROJECT_ID/logs/appengine.googleapis.com/request_log"
    

    Für App Engine-Anwendungslogs (stdout/stderr):

    resource.type="gae_app"
    (logName="projects/PROJECT_ID/logs/stdout" OR logName="projects/PROJECT_ID/logs/stderr")
    

    Ersetzen Sie PROJECT_ID durch Ihre GCP-Projekt-ID.

  8. Klicken Sie auf Weiter.

  9. Prüfen Sie die Konfiguration und klicken Sie auf Senke erstellen.

Berechtigungen für die Identität des Autors der Senke erteilen

Nachdem Sie die Senke erstellt haben, müssen Sie der Identität des Autors der Senke die Rolle „Storage-Objekt-Ersteller“ für den Ziel-Bucket zuweisen. Die Identität des Autors für das Dienstkonto sieht in etwa so aus: serviceAccount:service-123456789012@gcp-sa-logging.iam.gserviceaccount.com

  1. Suchen Sie auf der Seite Log Router die neu erstellte Senke.
  2. Klicken Sie neben dem Namen des Waschbeckens auf das Dreipunkt-Menü.
  3. Wählen Sie Senkendetails aufrufen aus.
  4. Kopieren Sie die Identität des Autors (E-Mail-Adresse des Dienstkontos).
  5. Rufen Sie Cloud Storage > Buckets auf.
  6. Klicken Sie auf den Bucket-Namen (appengine-logs-export).
  7. Wechseln Sie zum Tab Berechtigungen.
  8. Klicken Sie auf Zugriff erlauben.
  9. Geben Sie die folgenden Konfigurationsdetails an:
    • Hauptkonten hinzufügen: Fügen Sie die Identität des Autors der Senke (E-Mail-Adresse des Dienstkontos) ein.
    • Rollen zuweisen: Wählen Sie Storage-Objekt-Ersteller aus.
  10. Klicken Sie auf Speichern.

Google SecOps-Dienstkonto abrufen

Google SecOps verwendet ein eindeutiges Dienstkonto, um Daten aus Ihrem GCS-Bucket zu lesen. Sie müssen diesem Dienstkonto Zugriff auf Ihren Bucket gewähren.

Feed in Google SecOps konfigurieren, um App Engine-Logs aufzunehmen

  1. Rufen Sie die SIEM-Einstellungen > Feeds auf.
  2. Klicken Sie auf Neuen Feed hinzufügen.
  3. Klicken Sie auf Einzelnen Feed konfigurieren.
  4. Geben Sie im Feld Feedname einen Namen für den Feed ein, z. B. App Engine Logs.
  5. Wählen Sie Google Cloud Storage V2 als Quelltyp aus.
  6. Wählen Sie GCP_APP_ENGINE als Logtyp aus.

  7. Klicken Sie auf Dienstkonto abrufen.

  8. Es wird eine eindeutige E-Mail-Adresse für das Dienstkonto angezeigt, z. B.:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  9. Kopieren Sie diese E-Mail-Adresse. Sie verwenden es in der nächsten Aufgabe.

  10. Klicken Sie auf Weiter.

  11. Geben Sie Werte für die folgenden Eingabeparameter an:

    • Storage-Bucket-URL: Geben Sie den GCS-Bucket-URI mit dem Präfixpfad ein:

      gs://appengine-logs-export/
      

      In Cloud Logging werden exportierte Logdateien nach Logtyp und Datum in Verzeichnishierarchien organisiert. Der Logtyp kann ein zusammengesetzter Name wie appengine.googleapis.com/request_log sein. Die Dateien sind fragmentiert und werden nach Zeiträumen benannt (z. B. 08:00:00_08:59:59_S0.json).

    • Option zum Löschen der Quelle: Wählen Sie die gewünschte Löschoption aus:

      • Nie: Es werden nach Übertragungen nie Dateien gelöscht (empfohlen für Tests).
      • Übertragene Dateien löschen: Dateien werden nach der erfolgreichen Übertragung gelöscht.
      • Übertragene Dateien und leere Verzeichnisse löschen: Dateien und leere Verzeichnisse werden nach der erfolgreichen Übertragung gelöscht.
    • Maximales Dateialter: Dateien einschließen, die in den letzten Tagen geändert wurden. Der Standardwert ist 180 Tage.

    • Asset-Namespace: Der Asset-Namespace.

    • Aufnahmelabels: Das Label, das auf die Ereignisse aus diesem Feed angewendet werden soll.

  12. Klicken Sie auf Weiter.

  13. Prüfen Sie die neue Feedkonfiguration auf dem Bildschirm Abschließen und klicken Sie dann auf Senden.

Dem Google SecOps-Dienstkonto IAM-Berechtigungen gewähren

Das Google SecOps-Dienstkonto benötigt die Rolle Storage-Objekt-Betrachter für Ihren GCS-Bucket.

  1. Rufen Sie Cloud Storage > Buckets auf.
  2. Klicken Sie auf den Bucket-Namen (appengine-logs-export).
  3. Wechseln Sie zum Tab Berechtigungen.
  4. Klicken Sie auf Zugriff erlauben.
  5. Geben Sie die folgenden Konfigurationsdetails an:
    • Hauptkonten hinzufügen: Fügen Sie die E‑Mail-Adresse des Google SecOps-Dienstkontos ein.
    • Rollen zuweisen: Wählen Sie Storage-Objekt-Betrachter aus.
  6. Klicken Sie auf Speichern.

App Engine-Logstruktur

App Engine sendet automatisch sowohl Anfrage- als auch Anwendungslogs an Cloud Logging. App Engine gibt automatisch Logs für Anfragen aus, die an Ihre Anwendung gesendet werden, sodass Sie keine Anfragelogs schreiben müssen. In diesem Abschnitt wird beschrieben, wie Anwendungslogs geschrieben werden.

App Engine-Anfragelogs enthalten Logeinträge mit protoPayload-Feldern, die Objekte vom Typ RequestLog mit @type "type.googleapis.com/google.appengine.logging.v1.RequestLog" enthalten. Der Ressourcentyp ist „gae_app“.

Standardmäßig ist die Lognutzlast ein Textstring, der im Feld „textPayload“ des Logeintrags gespeichert wird. Die Strings werden im Log-Explorer als Nachrichten angezeigt und sind mit dem App Engine-Dienst sowie mit der Version verknüpft, mit der sie ausgegeben wurden.

Wenn Sie strukturierte Logs schreiben möchten, schreiben Sie Logs in Form einer einzelnen Zeile mit serialisiertem JSON. Wenn Sie ein strukturiertes Log als JSON-Wörterbuch erstellen, werden bestimmte Felder aus „jsonPayload“ entfernt und in das entsprechende Feld im generierten „LogEntry“ geschrieben. Wenn Ihr JSON beispielsweise das Attribut „severity“ enthält, wird es aus „jsonPayload“ entfernt und stattdessen als „severity“ des Logeintrags angezeigt.

Bekannte Einschränkungen

Wenn Sie Logs von der Logsenke nach Cloud Storage weiterleiten, enthält das Cloud Storage-Ziel nur Anfragelogs. App Engine schreibt Anwendungslogs in verschiedene Ordner.

Weitergeleitete Log-Einträge werden stündlich in Batches in Cloud Storage-Buckets gespeichert. Es kann zwei bis drei Stunden dauern, bis die ersten Einträge angezeigt werden.

In der flexiblen App Engine-Umgebung funktioniert das Logging automatisch. Allerdings erfolgt die Erfassung der Logs in einem unterschiedlichen Format. Sie werden nicht nach Anfragen gebündelt und Logs von stdout und stderr werden gesondert erfasst.

UDM-Zuordnungstabelle

Logfeld UDM-Zuordnung Logik
jsonPayload.logger, taskTypeName, jsonPayload.@type, jsonPayload.backendTargetProjectNumber, jsonPayload.cacheDecision, resource.labels.version_id, resource.labels.module_id, logName, spanId, trace, protoPayload.@type, labels.clone_id, operation.producer additional.fields Mit Schlüssel/Wert-Labels zusammengeführt, die aus jedem Feld erstellt wurden
Metadaten Metadaten Umbenannt von „Metadaten“
receiveTimestamp metadata.collected_timestamp Mit Datumsfilter mit RFC 3339 geparst
metadata.event_type Auf „USER_LOGIN“ setzen, wenn has_principal, has_target, has_principal_user; „NETWORK_CONNECTION“, wenn has_principal und has_target; „USER_UNCATEGORIZED“, wenn nicht has_principal und has_target; „STATUS_UPDATE“, wenn has_principal; „USER_UNCATEGORIZED“, wenn has_principal_user; andernfalls „GENERIC_EVENT“
metadata.extensions.auth.type Auf „AUTHTYPE_UNSPECIFIED“ festgelegt, wenn has_principal, has_target und has_principal_user
insertId metadata.product_log_id Wert direkt kopiert
httpRequest.requestMethod,protoPayload.method network.http.method Wert aus httpRequest.requestMethod, falls nicht leer, andernfalls protoPayload.method
httpRequest.userAgent network.http.parsed_user_agent In „parseduseragent“ konvertiert
httpRequest.status network.http.response_code In String und dann in Ganzzahl konvertiert
httpRequest.userAgent network.http.user_agent Wert direkt kopiert
httpRequest.responseSize network.received_bytes In „uinteger“ konvertiert
httpRequest.requestSize network.sent_bytes In „uinteger“ konvertiert
Prinzipal Prinzipal Umbenannt aus „principal“, falls nicht leer
protoPayload.host principal.asset.hostname Wert direkt kopiert
httpRequest.serverIp, protoPayload.ip principal.asset.ip Mit „server_ip“ aus „httpRequest.serverIp“ oder „protoPayload.ip“ zusammengeführt
protoPayload.host principal.hostname Wert direkt kopiert
httpRequest.serverIp, protoPayload.ip principal.ip Mit „server_ip“ aus „httpRequest.serverIp“ oder „protoPayload.ip“ zusammengeführt
protoPayload.appId principal.resource.attribute.labels Zusammengeführt mit „appId_label“ mit dem Schlüssel „appId“ und dem Wert aus dem Feld
requestUser principal.user.email_addresses Mit „requestUser“ zusammengeführt, wenn die E-Mail-Adresse dem E-Mail-Muster entspricht
security_result security_result Zusammengeführt aus security_result
resource.labels.forwarding_rule_name security_result.rule_labels Zusammengeführt mit „rule_label“ mit dem Schlüssel „forwarding_rule_name“ und dem Wert aus dem Feld
die Ausprägung security_result.severity Auf „severity“ setzen, wenn (?i)ERROR|CRITICAL zutrifft, auf „INFORMATIONAL“, wenn (?i)INFO zutrifft, auf „MEDIUM“, wenn (?i)WARN zutrifft, auf „LOW“, wenn (?i)DEBUG zutrifft, andernfalls auf „UNKNOWN_SEVERITY“
jsonPayload.statusDetails security_result.summary Wert direkt kopiert
Ziel Ziel Aus dem Ziel umbenannt, wenn nicht leer
resource.labels.backend_service_name target.application Wert direkt kopiert
httpRequest.remoteIp, jsonPayload.remoteIp target.asset.ip Wird mit „remote_ip“ zusammengeführt, das aus „httpRequest.remoteIp“ oder „jsonPayload.remoteIp“ extrahiert wurde.
resource.labels.project_id target.cloud.project.name Wert direkt kopiert
httpRequest.remoteIp, jsonPayload.remoteIp target.ip Zusammengeführt mit „remote_ip“, das aus „httpRequest.remoteIp“ oder „jsonPayload.remoteIp“ extrahiert wurde
resource.labels.zone target.resource.attribute.cloud.availability_zone Wert direkt kopiert
resource.labels.target_proxy_name, resource.labels.url_map_name target.resource.attribute.labels Mit Labels aus jeder Quelle zusammengeführt
resource.type target.resource.type Wert direkt kopiert
httpRequest.requestUrl target.url Wert direkt kopiert
metadata.product_name Auf „GCP_APP_ENGINE“ festlegen
metadata.vendor_name Auf „GCP“ festgelegt
protoPayload.requestMetadata.callerIp event.idm.read_only_udm.principal.ip Aus dem Änderungsprotokoll zugeordnet
protoPayload.requestMetadata.callerIp event.idm.read_only_udm.principal.asset.ip Aus dem Änderungsprotokoll zugeordnet
protoPayload.authenticationInfo.principalEmail event.idm.read_only_udm.principal.user.email_addresses Aus dem Änderungsprotokoll zugeordnet
protoPayload.methodName event.idm.read_only_udm.metadata.product_event_type Aus dem Änderungsprotokoll zugeordnet
protoPayload.resourceName event.idm.read_only_udm.target.resource.name Aus dem Änderungsprotokoll zugeordnet
protoPayload.serviceName event.idm.read_only_udm.target.application Aus dem Änderungsprotokoll zugeordnet
protoPayload.resourceLocation.currentLocations event.idm.read_only_udm.target.resource.attribute.labels Aus dem Änderungsprotokoll zugeordnet
protoPayload.authenticationInfo.oauthInfo.oauthClientId event.idm.read_only_udm.principal.resource.attribute.labels Aus dem Änderungsprotokoll zugeordnet
protoPayload.requestMetadata.requestAttributes.time event.idm.read_only_udm.additional.fields Aus dem Änderungsprotokoll zugeordnet
operation.first event.idm.read_only_udm.additional.fields Aus dem Änderungsprotokoll zugeordnet
protoPayload.serviceData.updateService.request.updateMask event.idm.read_only_udm.additional.fields Aus dem Änderungsprotokoll zugeordnet
operation.id event.idm.read_only_udm.additional.fields Aus dem Änderungsprotokoll zugeordnet
protoPayload.authenticationInfo.serviceAccountKeyName event.idm.read_only_udm.additional.fields Aus dem Änderungsprotokoll zugeordnet
protoPayload.authorizationInfo.permission event.idm.read_only_udm.security_result.rule_name Aus dem Änderungsprotokoll zugeordnet
protoPayload.authorizationInfo.permissionType event.idm.read_only_udm.security_result.description Aus dem Änderungsprotokoll zugeordnet
protoPayload.authorizationInfo.granted event.idm.read_only_udm.security_result.action Aus dem Änderungsprotokoll zugeordnet
protoPayload.@type" , "labels.clone_id" and "operation.producer additional.labels Aus dem Änderungsprotokoll zugeordnet

Änderungsprotokoll

Änderungsprotokoll für diesen Parser ansehen

Benötigen Sie weitere Hilfe? Antworten von Community-Mitgliedern und Google SecOps-Experten erhalten