Recopila registros de GitLab
Descripción general
Este analizador extrae campos de los registros JSON de GitLab, los normaliza en el modelo de datos unificado (UDM) y enriquece los datos con contexto adicional. Maneja varios tipos de eventos de GitLab, enfocándose en las acciones del usuario, el acceso a los recursos y los resultados de seguridad, y también procesa información relacionada con la red y la aplicación. El analizador también realiza la lógica en función de los roles y las acciones dentro de GitLab, categorizando los eventos y asignando las gravedades adecuadas.
Antes de comenzar
Asegúrate de cumplir con los siguientes requisitos previos:
- Instancia de Google SecOps.
- Acceso privilegiado a GitLab
Configura feeds
Para configurar un feed, sigue estos pasos:
- Ve a Configuración del SIEM > Feeds.
- Haz clic en Agregar feed nuevo.
- En la siguiente página, haz clic en Configurar un solo feed.
- En el campo Nombre del feed, ingresa un nombre para el feed (por ejemplo, Registros de GitLab).
- Selecciona Webhook como el Tipo de origen.
- Selecciona Gitlab como el Tipo de registro.
- Haz clic en Siguiente.
- Opcional: Especifica valores para los siguientes parámetros de entrada:
- Delimitador de división: Es el delimitador que se usa para separar las líneas de registro, como
\n
. - Espacio de nombres del recurso: Es el espacio de nombres del recurso.
- Etiquetas de transferencia: Es la etiqueta que se aplica a los eventos de este feed.
- Delimitador de división: Es el delimitador que se usa para separar las líneas de registro, como
- Haz clic en Siguiente.
- Revisa la configuración del feed en la pantalla Finalizar y, luego, haz clic en Enviar.
- Haz clic en Generar clave secreta para generar una clave secreta que autentique este feed.
- Copia y almacena la clave secreta. No podrás volver a ver esta clave secreta. Si es necesario, puedes regenerar una clave secreta nueva, pero esta acción hace que la clave secreta anterior quede obsoleta.
- En la pestaña Detalles, copia la URL del extremo del feed del campo Información del extremo. Debes especificar esta URL de extremo en tu aplicación cliente.
- Haz clic en Listo.
Crea una clave de API para el feed del webhook
Ve a Google Cloud consola > Credenciales.
Haz clic en Crear credenciales y selecciona Clave de API.
Restringe el acceso a la clave de API a la API de Chronicle.
Especifica la URL del extremo
- En tu aplicación cliente, especifica la URL del extremo HTTPS que se proporciona en el feed de webhook.
Para habilitar la autenticación, especifica la clave de API y la clave secreta como parte del encabezado personalizado con el siguiente formato:
X-goog-api-key = API_KEY X-Webhook-Access-Key = SECRET
Recomendación: Especifica la clave de API como un encabezado en lugar de hacerlo en la URL. Si tu cliente de webhook no admite encabezados personalizados, puedes especificar la clave de API y la clave secreta con parámetros de búsqueda en el siguiente formato:
ENDPOINT_URL?key=API_KEY&secret=SECRET
Reemplaza lo siguiente:
ENDPOINT_URL
: Es la URL del extremo del feed.API_KEY
: Es la clave de API para autenticarse en Google Security Operations.SECRET
: Es la clave secreta que generaste para autenticar el feed.
Configura un webhook en GitLab para Google SecOps
- Abre tu navegador web y ve al proyecto de GitLab para el que deseas configurar el webhook.
- En tu proyecto, ve a Configuración > Webhooks.
- Haz clic en Agregar webhook nuevo.
- En el campo URL, pega la URL del extremo de Google SecOps.
- Haz clic en Agregar encabezado personalizado.
- Escribe X-Webhook-Access-Key en el campo Nombre del encabezado.
- En el campo Header Value, copia la clave secreta que se generó durante la configuración del feed de Google SecOps.
- Haz clic en Agregar encabezado personalizado.
- Escribe X-goog-api-key en el campo Nombre del encabezado.
- En el campo Header Value, copia la clave de API que se generó durante la configuración del feed de SecOps de Google. Nota: Para mejorar la seguridad, genera un token secreto y agrégalo a la configuración del webhook de GitLab y a la configuración del feed de Google SecOps correspondiente. Esto ayuda a verificar la autenticidad de los webhooks entrantes.
- Elige los eventos de GitLab que deben activar el webhook. Por ejemplo, puedes seleccionar Eventos de envío para enviar datos a Google SecOps cada vez que se envíe código al repositorio. Considera cuidadosamente qué eventos son relevantes para tus necesidades de supervisión de seguridad. Demasiados eventos pueden generar una carga innecesaria.
- Para comprender mejor el propósito del webhook, asígnale un nombre significativo, como Webhook de Google SecOps.
- Asegúrate de que la casilla de verificación Habilitar verificación de SSL esté seleccionada. Esto es fundamental para la comunicación segura.
- Haz clic en Agregar webhook para guardar la configuración.
Tabla de asignación de UDM
Campo de registro | Asignación de UDM | Lógica |
---|---|---|
author_id |
principal.user.userid |
Se convirtió en una cadena. |
author_name |
principal.user.email_addresses |
Si el valor coincide con una regex de dirección de correo electrónico. |
author_name |
principal.user.user_display_name |
Si el valor no coincide con una expresión regular de dirección de correo electrónico. |
details.as |
principal.resource.attribute.labels |
Se agregó como una etiqueta con la clave "as". |
details.add |
principal.resource.attribute.labels |
Se agregó como una etiqueta con la clave "add". |
details.as |
principal.user.role_name |
Es el valor del campo de registro sin procesar. |
details.as |
principal.user.attribute.roles.type |
Se establece en "ADMINISTRATOR" si details.as es "propietario", "SERVICE_ACCOUNT" si details.as es "Developer", "Maintainer" o "Reporter", y "TYPE_UNSPECIFIED" si details.as es "Guest". |
details.custom_message |
security_result.description |
Es el valor del campo de registro sin procesar. |
details.custom_message.action |
security_result.summary |
Es el valor del campo de registro sin procesar. |
details.entity_path |
target.file.full_path |
Es el valor del campo de registro sin procesar. |
details.target_id |
target.resource.id |
Se convirtió en una cadena. |
entity_path |
target.file.full_path |
Es el valor del campo de registro sin procesar. |
entity_type |
target.resource.attribute.labels |
Se agregó como una etiqueta con la clave "Tipo de entidad". |
event_type |
metadata.product_event_type |
Es el valor del campo de registro sin procesar. |
insertId |
metadata.product_log_id |
Es el valor del campo de registro sin procesar. |
ip_address |
principal.ip , principal.asset.ip |
Es el valor del campo de registro sin procesar. |
jsonPayload.action |
additional.fields |
Se agregó como un campo con la clave "action" y el valor de cadena. |
jsonPayload.controller |
additional.fields |
Se agregó como un campo con la clave "controller" y el valor de cadena. |
jsonPayload.correlation_id |
principal.asset_id |
Tiene el prefijo "id: ". |
jsonPayload.cpu_s |
additional.fields |
Se agregó como un campo con la clave "cpu_s" y el valor de cadena. |
jsonPayload.details.custom_message.protocol |
network.application_protocol |
Se establece en "UNKNOWN_APPLICATION_PROTOCOL" si el valor es "web". De lo contrario, se convierte a mayúsculas. También se agrega como un campo adicional con la clave "Application Protocol" si el valor es "web". |
jsonPayload.mem_total_bytes |
additional.fields |
Se agregó como un campo con la clave "mem_total_bytes" y el valor de cadena. |
jsonPayload.meta_caller_id |
additional.fields |
Se agregó como un campo con la clave "Caller Id" y un valor de cadena. |
jsonPayload.meta_client_id |
target.user.userid |
Es el valor del campo de registro sin procesar. |
jsonPayload.meta_feature_category |
additional.fields |
Se agregó como un campo con la clave "Categoría de la función" y un valor de cadena. |
jsonPayload.meta_remote_ip |
principal.ip , principal.asset.ip |
Es el valor del campo de registro sin procesar, analizado como un array JSON y combinado en los campos de IP. |
jsonPayload.meta_user |
principal.user.userid |
Se usa como resguardo si jsonPayload.username está vacío. |
jsonPayload.method |
network.http.method |
Es el valor del campo de registro sin procesar. |
jsonPayload.path |
target.process.file.full_path |
Es el valor del campo de registro sin procesar. |
jsonPayload.pid |
target.process.pid |
Se convirtió en una cadena. |
jsonPayload.remote_ip |
principal.ip , principal.asset.ip |
Es el valor del campo de registro sin procesar. |
jsonPayload.request_urgency |
additional.fields |
Se agregó como un campo con la clave "Urgencia de la solicitud" y un valor de cadena. |
jsonPayload.severity |
security_result.severity |
Se establece en "INFORMATIONAL" si el valor es "INFO", en "ERROR" si el valor es "ERROR" y en "MEDIUM" si el valor es "NOTICE". |
jsonPayload.status |
network.http.response_code |
Se convierte en un número entero si no es "ACTIVE". |
jsonPayload.ua |
network.http.user_agent |
Es el valor del campo de registro sin procesar. |
jsonPayload.username |
principal.user.userid |
Es el valor del campo de registro sin procesar. |
jsonPayload.worker_id |
principal.application |
Es el valor del campo de registro sin procesar. |
labels.instance_name |
principal.hostname , principal.asset.hostname |
Es el valor del campo de registro sin procesar, que se usa si el mensaje contiene "Removing user". |
logName |
security_result.category_details |
Es el valor del campo de registro sin procesar. |
message |
security_result.summary |
Es el valor del campo de registro sin procesar, que se usa si jsonPayload.severity es "ERROR". |
protoPayload.@type |
additional.fields |
Se agregó como un campo con la clave "tipo de protoPayload" y el valor de cadena. |
protoPayload.authenticationInfo.principalEmail |
principal.user.email_addresses , principal.user.userid |
Es el valor del campo de registro sin procesar. |
protoPayload.authenticationInfo.principalSubject |
additional.fields |
Se agregó como un campo con la clave "authenticationInfo principalSubject" y el valor de cadena. |
protoPayload.authenticationInfo.serviceAccountKeyName |
additional.fields |
Se agregó como un campo con la clave "authenticationInfo serviceAccountKeyName" y el valor de cadena. |
protoPayload.authorizationInfo |
target.resource.attribute.labels , security_result.action |
Los valores de este campo se agregan como etiquetas con claves que tienen el prefijo "authenticationInfo". El security_result.action se establece en "ALLOW" si un valor dentro de granted es verdadero y en "BLOCK" si es falso. Los campos anidados, como resourceAttributes , también se agregan como etiquetas con claves que tienen el prefijo "authenticationInfo_resourceAttributes". |
protoPayload.methodName |
additional.fields |
Se agregó como un campo con la clave "protoPayload methodName" y el valor de cadena. |
protoPayload.request.@type |
additional.fields |
Se agregó como un campo con la clave "Tipo de solicitud" y un valor de cadena. |
protoPayload.request.resource |
target.resource.attribute.labels |
Se agregó como una etiqueta con la clave "Recurso de solicitud". |
protoPayload.requestMetadata.callerIp |
additional.fields |
Se agregó como un campo con la clave "requestMetadata callerIp" y el valor de cadena. |
protoPayload.requestMetadata.callerSuppliedUserAgent |
additional.fields |
Se agregó como un campo con la clave "requestMetadata callerSuppliedUserAgent" y el valor de cadena. |
protoPayload.serviceName |
additional.fields |
Se agregó como un campo con la clave "serviceName" y el valor de cadena. |
protoPayload.status.code |
additional.fields |
Se agregó como un campo con la clave "código de estado de protoPayload" y el valor de cadena. |
protoPayload.status.message |
additional.fields , target.user.email_addresses , target.user.userid |
Se agrega como un campo con la clave "mensaje de estado de protoPayload" y el valor de cadena. Si se puede extraer una dirección de correo electrónico del mensaje, se agrega a target.user.email_addresses y target.user.userid . |
receiveTimestamp |
metadata.event_timestamp , timestamp |
Se analiza como la marca de tiempo del evento. |
resource.labels.project_id |
target.resource.attribute.labels |
Se agregó como una etiqueta con la clave "ID del proyecto". |
resource.labels.zone |
target.cloud.availability_zone |
Es el valor del campo de registro sin procesar. |
resource.type |
target.cloud.environment |
Se establece en "GOOGLE_CLOUD_PLATFORM" si el valor coincide con "gce". |
security_result.action |
security_result.action |
Derivado de protoPayload.authorizationInfo.granted . |
security_result.category_details |
security_result.category_details |
Se combinó con logName . |
security_result.description |
security_result.description |
Derivado de jsonPayload.details.custom_message . |
security_result.severity |
security_result.severity |
Se deriva de severity o jsonPayload.severity . |
security_result.summary |
security_result.summary |
Se deriva de jsonPayload.details.custom_message.action o jsonPayload.message . |
severity |
security_result.severity |
Se establece en "INFORMATIONAL" si el valor es "INFO", en "ERROR" si el valor es "ERROR" y en "MEDIUM" si el valor es "NOTICE". |
sourceLocation |
principal.resource.attribute.labels |
Los valores de este campo se agregan como etiquetas. |
target_details |
target.resource.attribute.labels |
Se agregó como una etiqueta con la clave "Target Details". |
target_type |
target.resource.attribute.labels |
Se agregó como una etiqueta con la clave "target type". |
timestamp |
timestamp |
Es el valor del campo de registro sin procesar. Se establece según la presencia de los campos principal y objetivo. El valor predeterminado es "GENERIC_EVENT" si no se cumple ninguna condición específica. Los valores posibles son "USER_RESOURCE_UPDATE_CONTENT", "USER_RESOURCE_ACCESS" y "USER_UNCATEGORIZED". Se debe establecer en "GITLAB". Se debe establecer en "GITLAB". |
¿Necesitas más ayuda? Obtén respuestas de miembros de la comunidad y profesionales de Google SecOps.