Raccogliere i log di Google App Engine

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 dell'applicazione 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 disporre dei seguenti prerequisiti:

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

Creazione di 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, doppia regione, più regioni)
    Località Seleziona la posizione (ad esempio, us-central1).
    Classe di archiviazione Standard (consigliato per i log a cui si accede di frequente)
    Controllo dell'accesso Uniforme (consigliato)
    Strumenti di protezione (Facoltativo) Attiva 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 Cloud Logging

  1. Nella console Google Cloud, vai a Logging > Log Router.
  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 di richiesta e dell'applicazione):

    resource.type="gae_app"
    

    Solo per i log di richiesta 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 autorizzazioni all'identità di scrittura del sink

Dopo aver creato il sink, devi concedere all'identità di scrittura del sink il ruolo Storage Object Creator nel bucket di destinazione. L'identità del writer per il account di servizio ha un aspetto 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 del lavello.
  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 (email del account di servizio).
    • Assegna i ruoli: seleziona Storage Object Creator.
  10. Fai clic su Salva.

Recuperare il service account Google SecOps

Google SecOps utilizza un service account univoco per leggere i dati dal tuo bucket GCS. Devi concedere a questo service account 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.
  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à visualizzata un'email univoca del service account, 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 del 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 per tipo di log e 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 del 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 nella schermata Finalizza e poi fai clic su Invia.

Concedi le autorizzazioni IAM al service account Google SecOps

Il service account Google SecOps deve avere il ruolo Visualizzatore oggetti Storage nel 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'email del service account Google SecOps.
    • Assegna i 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.

I log di richiesta App Engine contengono voci di log con 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 Explorer log e sono associate al servizio e alla versione di App Engine che le hanno emesse.

Per scrivere log strutturati, scrivi i log sotto forma di una singola riga di JSON serializzato. Quando fornisci un log strutturato come dizionario JSON, alcuni campi speciali vengono rimossi da jsonPayload e scritti nel campo corrispondente della voce di log generata. Ad esempio, se il file JSON include una proprietà di gravità, 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 dalle 2 alle 3 ore prima che inizino a comparire 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 Logic
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 etichette chiave-valore create da ogni campo
metadati metadati Rinominate dai metadati
receiveTimestamp metadata.collected_timestamp Analizzato utilizzando il filtro per data con RFC3339
metadata.event_type Imposta "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 è vuoto
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 a appId_label contenente la chiave "appId" e il valore del campo
requestUser principal.user.email_addresses Unito a requestUser se corrisponde al pattern 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, su INFORMATIONAL se corrisponde a (?i)INFO, su MEDIUM se corrisponde a (?i)WARN, su LOW se corrisponde a (?i)DEBUG, altrimenti su UNKNOWN_SEVERITY
jsonPayload.statusDetails security_result.summary Valore copiato direttamente
target target Rinomina dalla destinazione 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 Imposta su "GCP"

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