GITHUB
En este documento se explica cómo ingerir registros de auditoría de GitHub en Google Security Operations mediante Amazon S3. El analizador intenta extraer datos del campo "message" mediante varios patrones grok, que gestionan formatos JSON y no JSON. En función del valor "process_type" extraído, aplica una lógica de análisis específica mediante grok, kv y otros filtros para asignar los datos de registro sin procesar al esquema del modelo de datos unificado (UDM).
Antes de empezar
Asegúrate de que cumples los siguientes requisitos previos:
- Instancia de Google SecOps.
- Acceso privilegiado al arrendatario de GitHub Enterprise Cloud con permisos de propietario de la empresa.
- Acceso privilegiado a AWS (S3, IAM).
Recopilar los requisitos previos de GitHub Enterprise Cloud (acceso Enterprise)
- Inicia sesión en la consola de administración de GitHub Enterprise Cloud.
- Ve a Configuración de empresa > Configuración > Registro de auditoría > Registro de streaming.
- Asegúrate de que tienes permisos de propietario de la empresa para configurar la transmisión de registros de auditoría.
- Copia y guarda en un lugar seguro los siguientes detalles:
- Nombre de GitHub Enterprise
- Nombres de organizaciones de la empresa
Configurar un segmento de AWS S3 y la gestión de identidades y accesos para Google SecOps
- Crea un segmento de Amazon S3 siguiendo esta guía de usuario: Crear un segmento.
- Guarda el nombre y la región del segmento para consultarlos más adelante (por ejemplo,
github-audit-logs
). - Crea un usuario siguiendo esta guía: Crear un usuario de gestión de identidades y accesos.
- Selecciona el Usuario creado.
- Selecciona la pestaña Credenciales de seguridad.
- En la sección Claves de acceso, haz clic en Crear clave de acceso.
- Selecciona Servicio de terceros en Caso práctico.
- Haz clic en Siguiente.
- Opcional: añade una etiqueta de descripción.
- Haz clic en Crear clave de acceso.
- Haz clic en Descargar archivo .CSV para guardar la clave de acceso y la clave de acceso secreta para futuras consultas.
- Haz clic en Listo.
Configurar la política de gestión de identidades y accesos para la transmisión de GitHub S3
- En la consola de AWS, vaya a IAM > Policies > Create policy > JSON tab (IAM > Políticas > Crear política > pestaña JSON).
- Copia y pega la siguiente política.
JSON de la política (sustituye
github-audit-logs
si has introducido otro nombre de contenedor):{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowPutObjects", "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::github-audit-logs/*" } ] }
Haz clic en Siguiente > Crear política.
Ponle un nombre a la política
GitHubAuditStreamingPolicy
y haz clic en Crear política.Vuelve al usuario de gestión de identidades y accesos que has creado antes.
Selecciona la pestaña Permisos.
Haz clic en Añadir permisos > Adjuntar políticas directamente.
Busca y selecciona
GitHubAuditStreamingPolicy
.Haz clic en Siguiente > Añadir permisos.
Configurar la transmisión de registros de auditoría de GitHub Enterprise Cloud
- Inicia sesión en GitHub Enterprise Cloud como propietario de la empresa.
- Haz clic en tu foto de perfil y, a continuación, en Configuración de Enterprise.
- En la barra lateral de la cuenta de empresa, haz clic en Configuración > Registro de auditoría > Registro de streaming.
- Selecciona Configurar flujo y haz clic en Amazon S3.
- En Autenticación, haz clic en Claves de acceso.
- Proporcione los siguientes detalles de configuración:
- Región: seleccione la región del contenedor (por ejemplo,
us-east-1
). - Segmento: escribe el nombre del segmento al que quieras enviar el contenido (por ejemplo,
github-audit-logs
). - Access Key ID (ID de clave de acceso): introduce el ID de clave de acceso del usuario de IAM.
- Clave secreta: introduce la clave secreta del usuario de IAM.
- Región: seleccione la región del contenedor (por ejemplo,
- Haz clic en Comprobar endpoint para verificar que GitHub puede conectarse al endpoint de Amazon S3 y escribir en él.
- Una vez que haya verificado correctamente el endpoint, haga clic en Guardar.
Crear un usuario y claves de IAM de solo lectura para Google SecOps
- Ve a Consola de AWS > IAM > Usuarios > Añadir usuarios.
- Haz clic en Add users (Añadir usuarios).
- Proporcione los siguientes detalles de configuración:
- Usuario: introduce
secops-reader
. - Tipo de acceso: selecciona Clave de acceso – Acceso programático.
- Usuario: introduce
- Haz clic en Crear usuario.
- Adjunta la política de lectura mínima (personalizada): Usuarios > lector-secops > Permisos > Añadir permisos > Adjuntar políticas directamente > Crear política.
JSON:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject"], "Resource": "arn:aws:s3:::github-audit-logs/*" }, { "Effect": "Allow", "Action": ["s3:ListBucket"], "Resource": "arn:aws:s3:::github-audit-logs" } ] }
Nombre =
secops-reader-policy
.Haz clic en Crear política > busca o selecciona > Siguiente > Añadir permisos.
Crea una clave de acceso para
secops-reader
: Credenciales de seguridad > Claves de acceso > Crear clave de acceso > descarga el archivo.CSV
(pegarás estos valores en el feed).
Configurar un feed en Google SecOps para ingerir registros de GitHub
- Ve a Configuración de SIEM > Feeds.
- Haz clic en + Añadir nuevo feed.
- En el campo Nombre del feed, introduce un nombre para el feed (por ejemplo,
GitHub audit logs
). - Selecciona Amazon S3 V2 como Tipo de fuente.
- Selecciona GitHub como Tipo de registro.
- Haz clic en Siguiente.
- Especifique los valores de los siguientes parámetros de entrada:
- URI de S3:
s3://github-audit-logs/
- Opciones de eliminación de la fuente: selecciona la opción de eliminación que prefieras.
- Antigüedad máxima del archivo: incluye los archivos modificados en los últimos días. El valor predeterminado es 180 días.
- ID de clave de acceso: clave de acceso de usuario con acceso al bucket de S3.
- Clave de acceso secreta: clave secreta del usuario con acceso al bucket de S3.
- Espacio de nombres de recursos: el espacio de nombres de recursos.
- Etiquetas de ingestión: la etiqueta aplicada a los eventos de este feed.
- URI de S3:
- Haz clic en Siguiente.
- Revise la configuración de la nueva fuente en la pantalla Finalizar y, a continuación, haga clic en Enviar.
Tabla de asignación de UDM
Campo de registro | Asignación de UDM | Lógica |
---|---|---|
actor |
principal.user.userid |
El valor se toma del campo actor . |
actor_id |
principal.user.attribute.labels.value |
El valor se toma del campo actor_id . |
actor_ip |
principal.ip |
El valor se toma del campo actor_ip . |
actor_location.country_code |
principal.location.country_or_region |
El valor se toma del campo actor_location.country_code . |
application_name |
target.application |
El valor se toma del campo application_name . |
business |
target.user.company_name |
El valor se toma del campo business . |
business_id |
target.resource.attribute.labels.value |
El valor se toma del campo business_id . |
config.url |
target.url |
El valor se toma del campo config.url . |
created_at |
metadata.event_timestamp |
El valor se convierte de milisegundos UNIX a una marca de tiempo. |
data.cancelled_at |
extensions.vulns.vulnerabilities.scan_end_time |
El valor se convierte del formato ISO8601 a una marca de tiempo. |
data.email |
target.email |
El valor se toma del campo data.email . |
data.event |
security_result.about.labels.value |
El valor se toma del campo data.event . |
data.events |
security_result.about.labels.value |
El valor se toma del campo data.events . |
data.head_branch |
security_result.about.labels.value |
El valor se toma del campo data.head_branch . |
data.head_sha |
target.file.sha256 |
El valor se toma del campo data.head_sha . |
data.hook_id |
target.resource.attribute.labels.value |
El valor se toma del campo data.hook_id . |
data.started_at |
extensions.vulns.vulnerabilities.scan_start_time |
El valor se convierte del formato ISO8601 a una marca de tiempo. |
data.team |
target.user.group_identifiers |
El valor se toma del campo data.team . |
data.trigger_id |
security_result.about.labels.value |
El valor se toma del campo data.trigger_id . |
data.workflow_id |
security_result.about.labels.value |
El valor se toma del campo data.workflow_id . |
data.workflow_run_id |
security_result.about.labels.value |
El valor se toma del campo data.workflow_run_id . |
enterprise.name |
additional.fields.value.string_value |
El valor se toma del campo enterprise.name . |
external_identity_nameid |
target.user.email_addresses |
Si el valor es una dirección de correo electrónico, se añade a la matriz target.user.email_addresses . |
external_identity_nameid |
target.user.userid |
El valor se toma del campo external_identity_nameid . |
external_identity_username |
target.user.user_display_name |
El valor se toma del campo external_identity_username . |
hashed_token |
network.session_id |
El valor se toma del campo hashed_token . |
job_name |
target.resource.attribute.labels.value |
El valor se toma del campo job_name . |
job_workflow_ref |
target.resource.attribute.labels.value |
El valor se toma del campo job_workflow_ref . |
org |
target.administrative_domain |
El valor se toma del campo org . |
org_id |
additional.fields.value.string_value |
El valor se toma del campo org_id . |
programmatic_access_type |
additional.fields.value.string_value |
El valor se toma del campo programmatic_access_type . |
public_repo |
additional.fields.value.string_value |
El valor se toma del campo public_repo . |
public_repo |
target.location.name |
Si el valor es "false", se asigna a "PRIVATE". De lo contrario, se asigna a "PUBLIC". |
query_string |
additional.fields.value.string_value |
El valor se toma del campo query_string . |
rate_limit_remaining |
additional.fields.value.string_value |
El valor se toma del campo rate_limit_remaining . |
repo |
target.resource.name |
El valor se toma del campo repo . |
repo_id |
additional.fields.value.string_value |
El valor se toma del campo repo_id . |
repository_public |
additional.fields.value.string_value |
El valor se toma del campo repository_public . |
request_body |
additional.fields.value.string_value |
El valor se toma del campo request_body . |
request_method |
network.http.method |
El valor se convierte a mayúsculas. |
route |
additional.fields.value.string_value |
El valor se toma del campo route . |
status_code |
network.http.response_code |
El valor se convierte en un número entero. |
timestamp |
metadata.event_timestamp |
El valor se convierte de milisegundos UNIX a una marca de tiempo. |
token_id |
additional.fields.value.string_value |
El valor se toma del campo token_id . |
token_scopes |
additional.fields.value.string_value |
El valor se toma del campo token_scopes . |
transport_protocol_name |
network.application_protocol |
El valor se convierte a mayúsculas. |
url_path |
target.url |
El valor se toma del campo url_path . |
user |
target.user.user_display_name |
El valor se toma del campo user . |
user_agent |
network.http.user_agent |
El valor se toma del campo user_agent . |
user_agent |
network.http.parsed_user_agent |
El valor se analiza. |
user_id |
target.user.userid |
El valor se toma del campo user_id . |
workflow.name |
security_result.about.labels.value |
El valor se toma del campo workflow.name . |
workflow_run.actor.login |
principal.user.userid |
El valor se toma del campo workflow_run.actor.login . |
workflow_run.event |
additional.fields.value.string_value |
El valor se toma del campo workflow_run.event . |
workflow_run.head_branch |
security_result.about.labels.value |
El valor se toma del campo workflow_run.head_branch . |
workflow_run.head_sha |
target.file.sha256 |
El valor se toma del campo workflow_run.head_sha . |
workflow_run.id |
target.resource.attribute.labels.value |
El valor se toma del campo workflow_run.id . |
workflow_run.workflow_id |
security_result.about.labels.value |
El valor se toma del campo workflow_run.workflow_id . |
N/A | metadata.event_type |
El valor se determina en función de los campos action y actor . Si el campo action contiene "_member", el valor se asigna a "USER_RESOURCE_UPDATE_PERMISSIONS". Si el campo action no está vacío y el campo actor tampoco, el valor se define como "USER_RESOURCE_UPDATE_CONTENT". De lo contrario, el valor será "USER_RESOURCE_ACCESS". |
N/A | metadata.log_type |
El valor es "GITHUB". |
N/A | metadata.product_name |
El valor es "GITHUB". |
N/A | metadata.vendor_name |
El valor es "GITHUB". |
N/A | target.resource.resource_type |
El valor es "STORAGE_OBJECT". |
N/A | security_result.about.labels.key |
El valor se asigna a una cadena constante basada en el campo data correspondiente. Por ejemplo, en data.workflow_id , la clave se define como "Workflow Id". |
N/A | target.resource.attribute.labels.key |
El valor se asigna a una cadena constante basada en el campo data correspondiente. Por ejemplo, en el caso de data.hook_id , la clave se define como "Hook Id". |
¿Necesitas más ayuda? Recibe respuestas de los miembros de la comunidad y de los profesionales de Google SecOps.