Raccogliere i log di GitLab
Panoramica
Questo analizzatore sintattico estrae i campi dai log JSON di GitLab, li normalizza nel modello di dati unificato (UDM) e arricchisce i dati con un contesto aggiuntivo. Gestisce vari tipi di eventi GitLab, concentrandosi su azioni utente, accesso alle risorse e risultati di sicurezza, oltre a elaborare informazioni relative alla rete e alle applicazioni. Il parser esegue anche la logica in base ai ruoli e alle azioni all'interno di GitLab, classifica gli eventi e assegna le gravità appropriate.
Prima di iniziare
- Assicurati di avere un'istanza Google SecOps.
- Assicurati di disporre di accesso con privilegi a GitLab.
Configura un feed in Google SecOps per importare i log di GitLab
- Vai a Impostazioni SIEM > Feed.
- Fai clic su Aggiungi nuovo.
- Nel campo Nome feed, inserisci un nome per il feed (ad esempio Log di GitLab).
- Seleziona Webhook come Tipo di origine.
- Seleziona Gitlab come Tipo di log.
- Fai clic su Avanti.
- (Facoltativo) Specifica i valori per i seguenti parametri di input:
- Delimitatore di split: il delimitatore utilizzato per separare le righe di log, ad esempio
\n
. - Spazio dei nomi degli asset: lo spazio dei nomi degli asset.
- Etichette di importazione: l'etichetta applicata agli eventi di questo feed.
- Delimitatore di split: il delimitatore utilizzato per separare le righe di log, ad esempio
- Fai clic su Avanti.
- Controlla la configurazione del feed nella schermata Concludi e poi fai clic su Invia.
- Fai clic su Genera chiave segreta per generare una chiave segreta per autenticare questo feed.
- Copia e memorizza la chiave segreta. Non potrai più visualizzare questa chiave segreta. Se necessario, puoi rigenerare una nuova chiave segreta, ma questa azione rende obsoleta la chiave segreta precedente.
- Nella scheda Dettagli, copia l'URL dell'endpoint del feed dal campo Informazioni endpoint. Devi specificare questo URL endpoint nell'applicazione client.
- Fai clic su Fine.
Crea una chiave API per il feed webhook
Vai alla console Google Cloud > Credenziali.
Fai clic su Crea credenziali e poi seleziona Chiave API.
Limita l'accesso alla chiave API all'API Google Security Operations.
Specifica l'URL dell'endpoint
- Nell'applicazione client, specifica l'URL dell'endpoint HTTPS fornito nel feed webhook.
Attiva l'autenticazione specificando la chiave API e la chiave segreta nell'intestazione personalizzata nel seguente formato:
X-goog-api-key = API_KEY X-Webhook-Access-Key = SECRET
Consiglio: specifica la chiave API come intestazione anziché nell'URL. Se il client webhook non supporta le intestazioni personalizzate, puoi specificare la chiave API e la chiave segreta utilizzando parametri di ricerca nel seguente formato:
ENDPOINT_URL?key=API_KEY&secret=SECRET
Sostituisci quanto segue:
ENDPOINT_URL
: l'URL dell'endpoint del feed.API_KEY
: la chiave API per l'autenticazione in Google Security Operations.SECRET
: la chiave segreta che hai generato per autenticare il feed.
Configurare un webhook in GitLab per Google SecOps
- Apri il browser web e vai al progetto GitLab per cui vuoi configurare l'webhook.
- Nel progetto, vai a Impostazioni > Webhook.
- Fai clic su Aggiungi nuovo webhook.
- Nel campo URL, incolla l'URL dell'endpoint Google SecOps.
- Fai clic su Aggiungi intestazione personalizzata.
- Digita X-Webhook-Access-Key nel campo Nome intestazione.
- Per il campo Header Value (Valore intestazione), copia la chiave segreta generata durante la configurazione del feed Google SecOps.
- Fai clic su Aggiungi intestazione personalizzata.
- Digita X-goog-api-key nel campo Nome intestazione.
- Per il campo Valore intestazione, copia la chiave API generata durante la configurazione del feed Google SecOps. Nota: per una maggiore sicurezza, genera un token segreto e aggiungilo sia alla configurazione dell'webhook di GitLab sia alla configurazione del feed Google SecOps corrispondente. In questo modo è possibile verificare l'autenticità dei webhook in entrata.
- Scegli gli eventi GitLab che devono attivare l'webhook. Ad esempio, puoi selezionare Eventi push per inviare dati a Google SecOps ogni volta che il codice viene inviato al repository. Valuta attentamente quali eventi sono pertinenti alle tue esigenze di monitoraggio della sicurezza. Troppi eventi possono causare un carico non necessario.
- Per comprendere meglio lo scopo dei webhook, assegna un nome significativo, ad esempio Webhook Google SecOps.
- Assicurati che la casella di controllo Attiva verifica SSL sia selezionata. Questo è fondamentale per la comunicazione sicura.
- Fai clic su Aggiungi webhook per salvare la configurazione.
Tabella di mappatura UDM
Campo log | Mappatura UDM | Logica |
---|---|---|
author_id |
principal.user.userid |
Convertito in stringa. |
author_name |
principal.user.email_addresses |
Se il valore corrisponde a un'espressione regolare dell'indirizzo email. |
author_name |
principal.user.user_display_name |
Se il valore non corrisponde a un'espressione regolare dell'indirizzo email. |
details.as |
principal.resource.attribute.labels |
Aggiunto come etichetta con chiave "as". |
details.add |
principal.resource.attribute.labels |
Aggiunto come etichetta con chiave "add". |
details.as |
principal.user.role_name |
Il valore del campo del log non elaborato. |
details.as |
principal.user.attribute.roles.type |
Imposta su "ADMINISTRATOR" se details.as è "Proprietario", su "SERVICE_ACCOUNT" se details.as è "Developer", "Maintainer" o "Reporter" e su "TYPE_UNSPECIFIED" se details.as è "Guest". |
details.custom_message |
security_result.description |
Il valore del campo del log non elaborato. |
details.custom_message.action |
security_result.summary |
Il valore del campo del log non elaborato. |
details.entity_path |
target.file.full_path |
Il valore del campo del log non elaborato. |
details.target_id |
target.resource.id |
Convertito in stringa. |
entity_path |
target.file.full_path |
Il valore del campo del log non elaborato. |
entity_type |
target.resource.attribute.labels |
Aggiunto come etichetta con chiave "Tipo di entità". |
event_type |
metadata.product_event_type |
Il valore del campo del log non elaborato. |
insertId |
metadata.product_log_id |
Il valore del campo del log non elaborato. |
ip_address |
principal.ip , principal.asset.ip |
Il valore del campo del log non elaborato. |
jsonPayload.action |
additional.fields |
Aggiunto come campo con chiave "action" e valore stringa. |
jsonPayload.controller |
additional.fields |
Aggiunto come campo con chiave "controller" e valore stringa. |
jsonPayload.correlation_id |
principal.asset_id |
Deve essere preceduto dal prefisso "id: ". |
jsonPayload.cpu_s |
additional.fields |
Aggiunto come campo con chiave "cpu_s" e valore stringa. |
jsonPayload.details.custom_message.protocol |
network.application_protocol |
Impostato su "UNKNOWN_APPLICATION_PROTOCOL" se il valore è "web", altrimenti viene convertito in maiuscolo. È stato aggiunto anche come campo aggiuntivo con la chiave "Application Protocol" se il valore è "web". |
jsonPayload.mem_total_bytes |
additional.fields |
Aggiunto come campo con chiave "mem_total_bytes" e valore stringa. |
jsonPayload.meta_caller_id |
additional.fields |
Aggiunto come campo con chiave "ID chiamante" e valore stringa. |
jsonPayload.meta_client_id |
target.user.userid |
Il valore del campo del log non elaborato. |
jsonPayload.meta_feature_category |
additional.fields |
Aggiunto come campo con chiave "Feature Category" e valore stringa. |
jsonPayload.meta_remote_ip |
principal.ip , principal.asset.ip |
Il valore del campo del log non elaborato, analizzato come array JSON e unito ai campi IP. |
jsonPayload.meta_user |
principal.user.userid |
Utilizzato come opzione di riserva se jsonPayload.username è vuoto. |
jsonPayload.method |
network.http.method |
Il valore del campo del log non elaborato. |
jsonPayload.path |
target.process.file.full_path |
Il valore del campo del log non elaborato. |
jsonPayload.pid |
target.process.pid |
Convertito in stringa. |
jsonPayload.remote_ip |
principal.ip , principal.asset.ip |
Il valore del campo del log non elaborato. |
jsonPayload.request_urgency |
additional.fields |
Aggiunto come campo con chiave "Urgenza richiesta" e valore stringa. |
jsonPayload.severity |
security_result.severity |
Impostato su "INFORMATIONAL" se il valore è "INFO", "ERROR" se il valore è "ERROR" e "MEDIUM" se il valore è "NOTICE". |
jsonPayload.status |
network.http.response_code |
Convertito in numero intero se non "ACTIVE". |
jsonPayload.ua |
network.http.user_agent |
Il valore del campo del log non elaborato. |
jsonPayload.username |
principal.user.userid |
Il valore del campo del log non elaborato. |
jsonPayload.worker_id |
principal.application |
Il valore del campo del log non elaborato. |
labels.instance_name |
principal.hostname , principal.asset.hostname |
Il valore del campo del log non elaborato, utilizzato se il messaggio contiene "Rimozione utente". |
logName |
security_result.category_details |
Il valore del campo del log non elaborato. |
message |
security_result.summary |
Il valore del campo del log non elaborato, utilizzato se jsonPayload.severity è "ERROR". |
protoPayload.@type |
additional.fields |
Aggiunto come campo con chiave "tipo di protoPayload" e valore stringa. |
protoPayload.authenticationInfo.principalEmail |
principal.user.email_addresses , principal.user.userid |
Il valore del campo del log non elaborato. |
protoPayload.authenticationInfo.principalSubject |
additional.fields |
Aggiunto come campo con chiave "authenticationInfo principalSubject" e valore stringa. |
protoPayload.authenticationInfo.serviceAccountKeyName |
additional.fields |
Aggiunto come campo con chiave "authenticationInfo serviceAccountKeyName" e valore stringa. |
protoPayload.authorizationInfo |
target.resource.attribute.labels , security_result.action |
I valori all'interno di questo campo vengono aggiunti come etichette con chiavi precedute da "authenticationInfo". security_result.action è impostato su "ALLOW" se un valore all'interno di granted è true e su "BLOCK" se è false. I campi nidificati come resourceAttributes vengono aggiunti anche come etichette con chiavi con prefisso "authenticationInfo_resourceAttributes". |
protoPayload.methodName |
additional.fields |
Aggiunto come campo con chiave "protoPayload methodName" e valore stringa. |
protoPayload.request.@type |
additional.fields |
Aggiunto come campo con chiave "Tipo di richiesta" e valore stringa. |
protoPayload.request.resource |
target.resource.attribute.labels |
Aggiunto come etichetta con chiave "Richiedi risorsa". |
protoPayload.requestMetadata.callerIp |
additional.fields |
Aggiunto come campo con chiave "requestMetadata callerIp" e valore stringa. |
protoPayload.requestMetadata.callerSuppliedUserAgent |
additional.fields |
Aggiunto come campo con chiave "requestMetadata callerSuppliedUserAgent" e valore stringa. |
protoPayload.serviceName |
additional.fields |
Aggiunto come campo con chiave "serviceName" e valore stringa. |
protoPayload.status.code |
additional.fields |
Aggiunto come campo con chiave "protoPayload status code" e valore stringa. |
protoPayload.status.message |
additional.fields , target.user.email_addresses , target.user.userid |
Aggiunto come campo con chiave "protoPayload status message" e valore stringa. Se è possibile estrarre un indirizzo email dal messaggio, questo viene aggiunto a target.user.email_addresses e target.user.userid . |
receiveTimestamp |
metadata.event_timestamp , timestamp |
Analizzata come timestamp dell'evento. |
resource.labels.project_id |
target.resource.attribute.labels |
Aggiunto come etichetta con chiave "Project id". |
resource.labels.zone |
target.cloud.availability_zone |
Il valore del campo del log non elaborato. |
resource.type |
target.cloud.environment |
Impostato su "GOOGLE_CLOUD_PLATFORM" se il valore corrisponde a "gce". |
security_result.action |
security_result.action |
Derivata da protoPayload.authorizationInfo.granted . |
security_result.category_details |
security_result.category_details |
Unito a logName . |
security_result.description |
security_result.description |
Derivata da jsonPayload.details.custom_message . |
security_result.severity |
security_result.severity |
Derivato da severity o jsonPayload.severity . |
security_result.summary |
security_result.summary |
Derivato da jsonPayload.details.custom_message.action o jsonPayload.message . |
severity |
security_result.severity |
Impostato su "INFORMATIONAL" se il valore è "INFO", "ERROR" se il valore è "ERROR" e "MEDIUM" se il valore è "NOTICE". |
sourceLocation |
principal.resource.attribute.labels |
I valori all'interno di questo campo vengono aggiunti come etichette. |
target_details |
target.resource.attribute.labels |
Aggiunto come etichetta con chiave "Dettagli target". |
target_type |
target.resource.attribute.labels |
Aggiunto come etichetta con chiave "tipo target". |
timestamp |
timestamp |
Il valore del campo del log non elaborato. Impostato in base alla presenza dei campi principale e target. Se non viene soddisfatta alcuna condizione specifica, il valore predefinito è "GENERIC_EVENT". I valori possibili sono "USER_RESOURCE_UPDATE_CONTENT", "USER_RESOURCE_ACCESS", "USER_UNCATEGORIZED". Impostato su "GITLAB". Impostato su "GITLAB". |
Modifiche
2024-04-08
- "custom_message.action" è stato mappato a "security_result.summary".
- "ip_address" è stato mappato a "principal.ip".
- "applicationProtocol" è stato mappato a "network.application_protocol".
- "details.author_name" è stato mappato a "principal.user.email_addresses"
- "author_id" è stato mappato a "principal.user.userid".
- "target_id" è stato mappato a "target.resource.id".
- "details.entity_path" è stato mappato a "target.file.full_path".
- "event_type" è stato mappato a "product_event_type".
- "target_type", "entity_type" e "target_details" sono stati mappati a "resource.attribute.labels".
2023-10-20
- I campi che iniziano con "db_" sono stati mappati a "additional_fields".
- I campi che iniziano con "redis_" sono stati mappati a "additional_fields".
- "severity" o "jsonPayload.severity" mappato a "security_result.severity" quando il valore è "ERROR" o "NOTICE".
- "jsonPayload.correlation_id" è stato mappato a "principal.asset_id".
- I "campi non mappati di jsonPayload" sono stati mappati a "additional_fields".
- "jsonPayload.worker_id" è stato mappato a "principal.application".
- "jsonPayload.method" è stato mappato a "network.http.method".
- "jsonPayload.pid" è stato mappato a "target.process.pid".
- "jsonPayload.status" è stato mappato a "network.http.response_code".
- "resource.labels.zone" è stato mappato a "target.cloud.availability_zone".
- "resource.type" è stato mappato a "target.cloud.environment".
- "jsonPayload.meta_user" è stato mappato a "target.user.userid".
- "jsonPayload.username" è stato mappato a "principal.user.userid".
- "jsonPayload.remote_ip" è stato mappato a "principal.ip".
- "jsonPayload.ua" è stato mappato a "network.http.user_agent".
- "jsonPayload.meta_client_id" è stato mappato a "target.user.userid".
- "jsonPayload.path" è stato mappato a "target.process.file.full_path".
- "protoPayload.authenticationInfo.principalEmail" è stato mappato a "principal.user.email_addresses".
- I campi aggiuntivi in "protoPayload" sono stati mappati a "additional.fields".
- È stato fornito un controllo condizionale che verifica la presenza della mappatura richiesta prima di mappare "metadata.event_type".
2023-10-10
- "jsonPayload.details.as" è stato mappato a "principal.resource.attribute.labels" e "principal.user.role_name".
- Imposta "principal_role.type" su "ADMINISTRATOR" per i log in cui "jsonPayload.details.as" è uguale a "Proprietario".
- Imposta "principal_role.type" su "SERVICE_ACCOUNT" per i log in cui "jsonPayload.details.as" è impostato su "Developer", "Maintainer" o "Reporter".
- Imposta "principal_role.type" su "TYPE_UNSPECIFIED" per i log in cui "jsonPayload.details.as" è uguale a "Ospite".
- È stata mappata "jsonPayload.details.add" a "principal.resource.attribute.labels".
- "jsonPayload.entity_type" è stato mappato a "target.resource.attribute.labels".
2023-08-31
- Parser appena creato.