Raccogli i log di Google App Engine
Versione parser: 3.0
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
- Vai alla console Google Cloud.
- Seleziona il tuo progetto o creane uno nuovo.
- Nel menu di navigazione, vai a Cloud Storage > Bucket.
- Fai clic su Crea bucket.
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 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
- Nella console Google Cloud, vai a Logging > Router dei log.
- Fai clic su Crea sink.
- Fornisci i seguenti dettagli di configurazione:
- Nome sink: inserisci un nome descrittivo (ad esempio
appengine-to-gcs). - Descrizione sink: descrizione facoltativa.
- Nome sink: inserisci un nome descrittivo (ad esempio
- Fai clic su Avanti.
- Nella sezione Seleziona il servizio sink:
- Servizio sink: seleziona Bucket Cloud Storage.
- Seleziona bucket Cloud Storage: seleziona
appengine-logs-exportdal menu a discesa.
- Fai clic su Avanti.
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_IDcon l'ID progetto GCP.Fai clic su Avanti.
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
- Nella pagina Router dei log, individua il sink appena creato.
- Fai clic sull'icona del menu (tre puntini verticali) accanto al nome del sink.
- Seleziona Visualizza dettagli sink.
- Copia l'identità writer (indirizzo email del account di servizio).
- Vai a Cloud Storage > Bucket.
- Fai clic sul nome del bucket (
appengine-logs-export). - Vai alla scheda Autorizzazioni.
- Fai clic su Concedi l'accesso.
- 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.
- 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
- Vai a Impostazioni SIEM > Feed.
- Fai clic su Aggiungi nuovo feed di notizie.
- Fai clic su Configura un singolo feed.
- Nel campo Nome feed, inserisci un nome per il feed (ad esempio
App Engine Logs). - Seleziona Google Cloud Storage V2 come Tipo di origine.
Seleziona GCP_APP_ENGINE come Tipo di log.
Fai clic su Ottieni service account.
Verrà visualizzato un indirizzo email univoco del account di servizio, ad esempio:
chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.comCopia l'indirizzo email. Lo utilizzerai nel prossimo passaggio.
Fai clic su Avanti.
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.
Fai clic su Avanti.
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.
- Vai a Cloud Storage > Bucket.
- Fai clic sul nome del bucket (
appengine-logs-export). - Vai alla scheda Autorizzazioni.
- Fai clic su Concedi l'accesso.
- Fornisci i seguenti dettagli di configurazione:
- Aggiungi entità: incolla l'indirizzo email del account di servizio Google SecOps.
- Assegna ruoli: seleziona Visualizzatore oggetti Storage.
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.