Raccogli i log di Google App Engine

Versione parser: 3.0

Supportato in:

Questo documento spiega come importare i log di Google App Engine in Google Security Operations utilizzando Google Cloud Storage V2.

Google App Engine è una piattaforma serverless completamente gestita per la creazione e il deployment di applicazioni web e API. App Engine genera automaticamente i log delle richieste per le richieste HTTP e i log delle applicazioni dal tuo codice. Questi log vengono inviati a Cloud Logging e possono essere esportati in Cloud Storage per l'importazione in Google Security Operations.

Prima di iniziare

Assicurati di soddisfare i seguenti prerequisiti:

  • Un'istanza Google SecOps
  • Un progetto GCP con l'API Storage di Cloud Storage abilitata
  • Autorizzazioni per creare e gestire bucket GCS
  • Autorizzazioni per gestire le policy IAM sui bucket GCS
  • Autorizzazioni per creare sink di Cloud Logging (roles/logging.configWriter)
  • Un'applicazione App Engine attiva (ambiente standard o flessibile)

Crea un bucket Google Cloud Storage

  1. Vai alla console Google Cloud.
  2. Seleziona il tuo progetto o creane uno nuovo.
  3. Nel menu di navigazione, vai a Cloud Storage > Bucket.
  4. Fai clic su Crea bucket.
  5. Fornisci i seguenti dettagli di configurazione:

    Impostazione Valore
    Assegna un nome al bucket Inserisci un nome univoco globale (ad esempio appengine-logs-export).
    Tipo di località Scegli in base alle tue esigenze (regione singola, a due regioni, multiregionale)
    Località Seleziona la località (ad esempio us-central1)
    Classe di archiviazione Standard (consigliato per i log a cui si accede di frequente)
    Controllo degli accessi Uniforme (consigliato)
    Strumenti di protezione (Facoltativo) Abilita il controllo delle versioni degli oggetti o la policy di conservazione
  6. Fai clic su Crea.

Configura Cloud Logging per esportare i log di App Engine in GCS

Cloud Logging utilizza i sink di log per instradare le voci di log verso destinazioni supportate, inclusi i bucket Cloud Storage. L'identità del writer del sink richiede il ruolo Creatore oggetti Storage (roles/storage.objectCreator) nel bucket di destinazione.

Crea un sink di Cloud Logging

  1. Nella console Google Cloud, vai a Logging > Router dei log.
  2. Fai clic su Crea sink.
  3. Fornisci i seguenti dettagli di configurazione:
    • Nome sink: inserisci un nome descrittivo (ad esempio appengine-to-gcs).
    • Descrizione sink: descrizione facoltativa.
  4. Fai clic su Avanti.
  5. Nella sezione Seleziona il servizio sink:
    • Servizio sink: seleziona Bucket Cloud Storage.
    • Seleziona bucket Cloud Storage: seleziona appengine-logs-export dal menu a discesa.
  6. Fai clic su Avanti.
  7. Nella sezione Scegli i log da includere nel sink, inserisci una query di filtro per selezionare i log di App Engine. Il tipo di risorsa deve essere esattamente "gae_app".

    Per tutti i log di App Engine (log delle richieste e delle applicazioni):

    resource.type="gae_app"
    

    Solo per i log delle richieste di App Engine:

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

    Per i log delle applicazioni App Engine (stdout/stderr):

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

    Sostituisci PROJECT_ID con l'ID progetto GCP.

  8. Fai clic su Avanti.

  9. Rivedi la configurazione e fai clic su Crea sink.

Concedi le autorizzazioni all'identità writer del sink

Dopo aver creato il sink, devi concedere all'identità writer del sink il ruolo Storage Object Creator nel bucket di destinazione. L'identità writer per il account di servizio è simile a: serviceAccount:service-123456789012@gcp-sa-logging.iam.gserviceaccount.com

  1. Nella pagina Router dei log, individua il sink appena creato.
  2. Fai clic sull'icona del menu (tre puntini verticali) accanto al nome del sink.
  3. Seleziona Visualizza dettagli sink.
  4. Copia l'identità writer (indirizzo email del account di servizio).
  5. Vai a Cloud Storage > Bucket.
  6. Fai clic sul nome del bucket (appengine-logs-export).
  7. Vai alla scheda Autorizzazioni.
  8. Fai clic su Concedi l'accesso.
  9. Fornisci i seguenti dettagli di configurazione:
    • Aggiungi entità: incolla l'identità del writer del sink (indirizzo email del account di servizio).
    • Assegna i ruoli: seleziona Storage Object Creator.
  10. Fai clic su Salva.

Recuperare il account di servizio Google SecOps

Google SecOps utilizza un account di servizio univoco per leggere i dati dal tuo bucket GCS. Devi concedere a questo account di servizio l'accesso al tuo bucket.

Configura un feed in Google SecOps per importare i log di App Engine

  1. Vai a Impostazioni SIEM > Feed.
  2. Fai clic su Aggiungi nuovo feed di notizie.
  3. Fai clic su Configura un singolo feed.
  4. Nel campo Nome feed, inserisci un nome per il feed (ad esempio App Engine Logs).
  5. Seleziona Google Cloud Storage V2 come Tipo di origine.
  6. Seleziona GCP_APP_ENGINE come Tipo di log.

  7. Fai clic su Ottieni service account.

  8. Verrà visualizzato un indirizzo email univoco del account di servizio, ad esempio:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  9. Copia l'indirizzo email. Lo utilizzerai nel prossimo passaggio.

  10. Fai clic su Avanti.

  11. Specifica i valori per i seguenti parametri di input:

    • URL bucket di archiviazione: inserisci l'URI del bucket GCS con il percorso del prefisso:

      gs://appengine-logs-export/
      

      Cloud Logging organizza i file di log esportati in gerarchie di directory in base al tipo di log e alla data. Il tipo di log può essere un nome composto come appengine.googleapis.com/request_log. I file vengono suddivisi e denominati in base ai periodi di tempo (ad esempio, 08:00:00_08:59:59_S0.json).

    • Opzione di eliminazione dell'origine: seleziona l'opzione di eliminazione in base alle tue preferenze:

      • Mai: non elimina mai i file dopo i trasferimenti (opzione consigliata per i test).
      • Elimina file trasferiti: elimina i file dopo il trasferimento riuscito.
      • Elimina file trasferiti e directory vuote: elimina i file e le directory vuote dopo il trasferimento riuscito.
    • Età massima file: includi i file modificati nell'ultimo numero di giorni. Il valore predefinito è 180 giorni.

    • Spazio dei nomi dell'asset: lo spazio dei nomi dell'asset.

    • Etichette di importazione: l'etichetta da applicare agli eventi di questo feed.

  12. Fai clic su Avanti.

  13. Controlla la nuova configurazione del feed di notizie nella schermata Finalizza, quindi fai clic su Invia.

Concedi le autorizzazioni IAM al account di servizio Google SecOps

Il account di servizio Google SecOps deve avere il ruolo Storage Object Viewer nel tuo bucket GCS.

  1. Vai a Cloud Storage > Bucket.
  2. Fai clic sul nome del bucket (appengine-logs-export).
  3. Vai alla scheda Autorizzazioni.
  4. Fai clic su Concedi l'accesso.
  5. Fornisci i seguenti dettagli di configurazione:
    • Aggiungi entità: incolla l'indirizzo email del account di servizio Google SecOps.
    • Assegna ruoli: seleziona Visualizzatore oggetti Storage.
  6. Fai clic su Salva.

Informazioni sulla struttura dei log di App Engine

App Engine invia automaticamente sia i log delle richieste sia i log delle app a Cloud Logging. App Engine genera automaticamente i log per le richieste inviate alla tua app, quindi non è necessario scrivere i log delle richieste. Questa sezione spiega come scrivere i log delle app.

Le voci dei log delle richieste di App Engine contengono campi protoPayload che contengono oggetti di tipo RequestLog con @type "type.googleapis.com/google.appengine.logging.v1.RequestLog". Il tipo di risorsa è "gae_app".

Per impostazione predefinita, il payload del log è una stringa di testo memorizzata nel campo textPayload della voce di log. Le stringhe vengono visualizzate come messaggi in Esplora log e sono associate al servizio e alla versione di App Engine che li ha emessi.

Per scrivere log strutturati, devi scrivere i log sotto forma di una singola riga con serializzazione JSON. Quando fornisci un log strutturato come dizionario JSON, alcuni campi speciali vengono rimossi da jsonPayload e scritti nel campo corrispondente della voce LogEntry generata. Ad esempio, se il file JSON include una proprietà severity, questa viene rimossa da jsonPayload e viene visualizzata come gravità della voce di log.

Limitazioni note

Quando indirizzi i log dal sink di log a Cloud Storage, la destinazione Cloud Storage contiene solo i log delle richieste. App Engine scrive i log delle app in cartelle diverse.

Le voci di log con routing vengono salvate nei bucket Cloud Storage in batch orari. Potrebbero essere necessarie da 2 a 3 ore prima che inizino a essere visualizzate le prime voci.

Nell'ambiente flessibile di App Engine, la registrazione funziona automaticamente. Tuttavia, i log vengono raccolti in un formato diverso. I log non verranno raggruppati per richieste e i log di stdout e stderr vengono raccolti separatamente.

Tabella di mappatura UDM

Campo log mappatura UDM Logica
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 Unite alle coppie chiave-valore create da ogni campo
metadati metadati Rinominato dai metadati
receiveTimestamp metadata.collected_timestamp Analizzato utilizzando il filtro data con RFC 3339
metadata.event_type Impostato su "USER_LOGIN" se has_principal, has_target, has_principal_user; "NETWORK_CONNECTION" se has_principal e has_target; "USER_UNCATEGORIZED" se non has_principal e has_target; "STATUS_UPDATE" se has_principal; "USER_UNCATEGORIZED" se has_principal_user; altrimenti "GENERIC_EVENT"
metadata.extensions.auth.type Imposta su "AUTHTYPE_UNSPECIFIED" se has_principal, has_target, has_principal_user
insertId metadata.product_log_id Valore copiato direttamente
httpRequest.requestMethod,protoPayload.method network.http.method Valore di httpRequest.requestMethod se non è vuoto, altrimenti protoPayload.method
httpRequest.userAgent network.http.parsed_user_agent Convertito in parseduseragent
httpRequest.status network.http.response_code Convertito in stringa e poi in numero intero
httpRequest.userAgent network.http.user_agent Valore copiato direttamente
httpRequest.responseSize network.received_bytes Convertito in uinteger
httpRequest.requestSize network.sent_bytes Convertito in uinteger
entità entità Rinomina da entità se non è vuota
protoPayload.host principal.asset.hostname Valore copiato direttamente
httpRequest.serverIp, protoPayload.ip principal.asset.ip Unito a server_ip da httpRequest.serverIp o protoPayload.ip
protoPayload.host principal.hostname Valore copiato direttamente
httpRequest.serverIp, protoPayload.ip principal.ip Unito a server_ip da httpRequest.serverIp o protoPayload.ip
protoPayload.appId principal.resource.attribute.labels Unito ad appId_label contenente la chiave "appId" e il valore del campo
requestUser principal.user.email_addresses Unito a requestUser se corrisponde al pattern dell'email
security_result security_result Unito da security_result
resource.labels.forwarding_rule_name security_result.rule_labels Unito a rule_label contenente la chiave "forwarding_rule_name" e il valore del campo
gravità security_result.severity Impostato su gravità se corrisponde a (?i)ERROR|CRITICAL, INFORMATIONAL se corrisponde a (?i)INFO, MEDIUM se corrisponde a (?i)WARN, LOW se corrisponde a (?i)DEBUG, altrimenti UNKNOWN_SEVERITY
jsonPayload.statusDetails security_result.summary Valore copiato direttamente
destinazione destinazione Rinominato dal target se non vuoto
resource.labels.backend_service_name target.application Valore copiato direttamente
httpRequest.remoteIp, jsonPayload.remoteIp target.asset.ip Unito a remote_ip estratto da httpRequest.remoteIp o jsonPayload.remoteIp
resource.labels.project_id target.cloud.project.name Valore copiato direttamente
httpRequest.remoteIp, jsonPayload.remoteIp target.ip Unito a remote_ip estratto da httpRequest.remoteIp o jsonPayload.remoteIp
resource.labels.zone target.resource.attribute.cloud.availability_zone Valore copiato direttamente
resource.labels.target_proxy_name, resource.labels.url_map_name target.resource.attribute.labels Unite alle etichette di ogni origine
resource.type target.resource.type Valore copiato direttamente
httpRequest.requestUrl target.url Valore copiato direttamente
metadata.product_name Impostato su "GCP_APP_ENGINE"
metadata.vendor_name Impostato su "GCP"
protoPayload.requestMetadata.callerIp event.idm.read_only_udm.principal.ip Mappato dal log delle modifiche
protoPayload.requestMetadata.callerIp event.idm.read_only_udm.principal.asset.ip Mappato dal log delle modifiche
protoPayload.authenticationInfo.principalEmail event.idm.read_only_udm.principal.user.email_addresses Mappato dal log delle modifiche
protoPayload.methodName event.idm.read_only_udm.metadata.product_event_type Mappato dal log delle modifiche
protoPayload.resourceName event.idm.read_only_udm.target.resource.name Mappato dal log delle modifiche
protoPayload.serviceName event.idm.read_only_udm.target.application Mappato dal log delle modifiche
protoPayload.resourceLocation.currentLocations event.idm.read_only_udm.target.resource.attribute.labels Mappato dal log delle modifiche
protoPayload.authenticationInfo.oauthInfo.oauthClientId event.idm.read_only_udm.principal.resource.attribute.labels Mappato dal log delle modifiche
protoPayload.requestMetadata.requestAttributes.time event.idm.read_only_udm.additional.fields Mappato dal log delle modifiche
operation.first event.idm.read_only_udm.additional.fields Mappato dal log delle modifiche
protoPayload.serviceData.updateService.request.updateMask event.idm.read_only_udm.additional.fields Mappato dal log delle modifiche
operation.id event.idm.read_only_udm.additional.fields Mappato dal log delle modifiche
protoPayload.authenticationInfo.serviceAccountKeyName event.idm.read_only_udm.additional.fields Mappato dal log delle modifiche
protoPayload.authorizationInfo.permission event.idm.read_only_udm.security_result.rule_name Mappato dal log delle modifiche
protoPayload.authorizationInfo.permissionType event.idm.read_only_udm.security_result.description Mappato dal log delle modifiche
protoPayload.authorizationInfo.granted event.idm.read_only_udm.security_result.action Mappato dal log delle modifiche
protoPayload.@type" , "labels.clone_id" and "operation.producer additional.labels Mappato dal log delle modifiche

Log delle modifiche

Visualizza il log delle modifiche per questo parser

Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.