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
Existen dos puntos de entrada diferentes para configurar feeds en la plataforma de Google SecOps:
- Configuración de SIEM > Feeds
- Centro de contenido > Paquetes de contenido
Configura feeds en Configuración del SIEM > 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.
Configura feeds desde el Centro de contenido
Especifica valores para los siguientes campos:
- Delimitador de división: Es el delimitador que se usa para separar las líneas de registro, como
\n
.
Opciones avanzadas
- Nombre del feed: Es un valor completado previamente que identifica el feed.
- Tipo de fuente: Es el método que se usa para recopilar registros en Google SecOps.
- Espacio de nombres del activo: Es el espacio de nombres asociado con el feed.
Etiquetas de transferencia: Son las etiquetas que se aplican a todos los eventos de este feed.
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.
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 SecOps de Google.
- 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 Google SecOps. 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.