Recoger registros DNS de Cisco Umbrella
En este documento se explica cómo recoger registros DNS de Cisco Umbrella en un feed de Google Security Operations mediante un contenedor de AWS S3. El analizador gestiona los registros con formato JSON y CSV. Extrae campos, les cambia el nombre para que coincidan con el UDM, gestiona diferentes versiones y formatos de registro (incluidos los registros de proxy y de IP) y aplica una lógica específica a las identidades, las categorías de seguridad y los eventos de red. Por último, combina los datos extraídos en el esquema del UDM.
Antes de empezar
- Asegúrate de que tienes una instancia de Google SecOps.
- Asegúrate de que tienes acceso privilegiado a AWS IAM y S3.
- Asegúrate de que tienes acceso con privilegios a Cisco Umbrella.
Configurar un segmento de Amazon S3 gestionado por Cisco
- Inicia sesión en el panel de control de Cisco Umbrella.
- Vaya a Administrar > Gestión de registros.
- Seleccione la opción Usar un segmento de Amazon S3 gestionado por Cisco.
- Proporcione los siguientes detalles de configuración:
- Selecciona una región: elige una región más cercana a tu ubicación para reducir la latencia.
- Seleccione un periodo de conservación: elija el periodo. La duración de la conservación es de 7, 14 o 30 días. Una vez transcurrido el periodo seleccionado, los datos se eliminan y no se pueden recuperar. Si tu ciclo de ingestión es regular, usa un periodo más corto. Puedes cambiar la duración de la conservación más adelante.
- Haz clic en Guardar.
- Haz clic en Continuar para confirmar tus selecciones y recibir la notificación de activación.
En la ventana Activación completada que aparece, se muestran los valores de Clave de acceso y Clave secreta. - Copia los valores de Clave de acceso y Clave secreta. Si pierdes estas claves, debes volver a generarlas.
- Haz clic en Entendido > Continuar.
- En una página de resumen se muestra la configuración y el nombre del segmento. Puedes activar o desactivar el registro según lo requiera tu organización. Sin embargo, los registros se purgan en función de la duración de la conservación, independientemente de si se añaden datos nuevos.
Opcional: Configurar claves de acceso de usuario para un segmento de AWS S3 autogestionado
- Inicia sesión en la consola de administración de AWS.
- 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 como 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 usarlas más adelante.
- Haz clic en Listo.
- Selecciona la pestaña Permisos.
- En la sección Políticas de permisos, haz clic en Añadir permisos.
- Selecciona Añadir permisos.
- Seleccione Adjuntar políticas directamente.
- Busca y selecciona la política AmazonS3FullAccess.
- Haz clic en Siguiente.
- Haz clic en Añadir permisos.
Opcional: Configurar un segmento de Amazon S3 autogestionado
Inicia sesión en la consola de administración de AWS.
.Ve a S3.
Haz clic en Crear segmento.
Proporciona los siguientes detalles de configuración:
- Nombre del segmento: indica un nombre para el segmento de Amazon S3.
- Región: selecciona una región.
Haz clic en Crear.
Opcional: Configurar una política de segmentos para un segmento de AWS S3 autogestionado
- Haz clic en el nuevo contenedor para abrirlo.
- Selecciona Propiedades > Permisos.
- En la lista Permisos, haga clic en Añadir política de contenedor.
Introduce la política de contenedor preconfigurada de la siguiente manera:
{ "Version": "2008-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::568526795995:user/logs" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::BUCKET_NAME/*" }, { "Sid": "", "Effect": "Deny", "Principal": { "AWS": "arn:aws:iam::568526795995:user/logs" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::BUCKET_NAME/*"}, { "Sid": "", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::568526795995:user/logs" }, "Action": "s3:GetBucketLocation", "Resource": "arn:aws:s3:::BUCKET_NAME" }, { "Sid": "", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::568526795995:user/logs" }, "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::BUCKET_NAME" } ] }
- Sustituye
BUCKET_NAME
por el nombre del segmento de Amazon S3 que has indicado.
- Sustituye
Haz clic en Guardar.
Opcional: verificación obligatoria para el segmento de Amazon S3 autogestionado
- En el panel de control de Cisco Umbrella, selecciona Administrador > Gestión de registros > Amazon S3.
- En el campo Nombre del segmento, especifica el nombre exacto del segmento de Amazon S3 y, a continuación, haz clic en Verificar.
- Como parte del proceso de verificación, se sube un archivo llamado
README_FROM_UMBRELLA.txt
de Cisco Umbrella a tu segmento de Amazon S3. Es posible que tengas que actualizar el navegador para ver el archivo Léame cuando se haya subido. - Descarga el archivo
README_FROM_UMBRELLA.txt
y ábrelo con un editor de texto. - Copia y guarda el token único de Cisco Umbrella del archivo.
- Ve al panel de control de Cisco Umbrella.
- En el campo Número de token, especifica el token y haz clic en Guardar.
- Si se verifica correctamente, recibirás un mensaje de confirmación en el panel de control que indica que el contenedor se ha verificado correctamente. Si recibes un error que indica que no se puede verificar tu contenedor, vuelve a comprobar la sintaxis del nombre del contenedor y revisa la configuración.
Configurar un feed en Google SecOps para ingerir los registros DNS de Cisco Umbrella
- Ve a Configuración de SIEM > Feeds.
- Haz clic en Añadir nuevo.
- En el campo Nombre del feed, introduce un nombre para el feed; por ejemplo, Registros DNS de Cisco Umbrella.
- Selecciona Amazon S3 V2 como Tipo de fuente.
- Selecciona Cisco Umbrella DNS como Tipo de registro.
- Haz clic en Siguiente.
Especifique los valores de los siguientes parámetros de entrada:
- URI de S3: el URI del segmento.
s3:/BUCKET_NAME/
- Sustituye
BUCKET_NAME
por el nombre real del segmento.
- Sustituye
- Opciones de eliminación de la fuente: selecciona la opción de eliminación que prefieras.
- URI de S3: el URI del segmento.
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 |
---|---|---|
action |
security_result.action_details |
El valor se toma del campo action si existe en los registros JSON o de column6 o column7 en los registros CSV, y se convierte a mayúsculas (ALLOW o BLOCK). |
amp.disposition |
security_result.detection_fields[].key |
El valor es ampDisposition . |
amp.disposition |
security_result.detection_fields[].value |
El valor se toma del campo amp.disposition . |
amp.malware |
security_result.detection_fields[].key |
El valor es ampMalware . |
amp.malware |
security_result.detection_fields[].value |
El valor se toma del campo amp.malware . |
amp.score |
security_result.detection_fields[].key |
El valor es ampScore . |
amp.score |
security_result.detection_fields[].value |
El valor se toma del campo amp.score . |
blocked_categories |
security_result.category_details |
El valor se toma del campo blocked_categories . |
blockedfiletype |
security_result.detection_fields[].key |
El valor es egress type . |
blockedfiletype |
security_result.detection_fields[].value |
El valor se toma del campo blockedfiletype . |
bundleid |
additional.fields[].key |
El valor es bundleid . |
bundleid |
additional.fields[].value.string_value |
El valor se toma del campo bundleid . |
categories[] |
security_result.category_details |
El valor se toma del campo categories[].label . |
column1 |
metadata.event_timestamp.seconds |
El valor se analiza a partir del campo column1 como una marca de tiempo. En el caso de los registros de proxy, si existen los campos date y time , se combinan y se analizan como una marca de tiempo. |
column10 |
network.http.user_agent |
El valor se toma del campo column10 . |
column10 |
additional.fields[].value.string_value |
El valor se toma del campo column10 . |
column11 |
target.port |
El valor se toma del campo column11 . |
column12 |
principal.resource.name |
El valor se toma del campo column12 . |
column13 |
security_result.rule_id |
El valor se toma del campo column13 . |
column14 |
security_result.action_details |
El valor se toma del campo column14 . |
column2 |
principal.user.user_display_name |
El valor se toma del campo column2 . |
column2 |
principal.user.userid |
El valor se toma del campo column2 . |
column2 |
principal.location.name |
El valor se toma del campo column2 . |
column3 |
principal.hostname |
El valor se toma del campo column3 . |
column3 |
principal.user.product_object_id |
El valor se toma del campo column3 . |
column3 |
principal.location.city |
El valor se toma del campo column3 . |
column3 |
additional.fields[].value.string_value |
El valor se toma del campo column3 . |
column4 |
principal.asset.ip |
El valor se toma del campo column4 . |
column4 |
principal.ip |
El valor se toma del campo column4 . |
column4 |
principal.port |
El valor se toma del campo column4 . |
column5 |
principal.asset.ip |
El valor se toma del campo column5 . |
column5 |
principal.ip |
El valor se toma del campo column5 . |
column5 |
target.asset.ip |
El valor se toma del campo column5 . |
column5 |
target.ip |
El valor se toma del campo column5 . |
column6 |
security_result.action_details |
El valor se toma del campo column6 . |
column6 |
target.port |
El valor se toma del campo column6 . |
column7 |
network.received_bytes |
El valor se toma del campo column7 . |
column7 |
additional.fields[].value.string_value |
El valor se toma del campo column7 . |
column8 |
principal.asset.ip |
El valor se toma del campo column8 . |
column8 |
principal.ip |
El valor se toma del campo column8 . |
column8 |
target.url |
El valor se toma del campo column8 . |
column9 |
principal.port |
El valor se toma del campo column9 . |
column9 |
network.http.referral_url |
El valor se toma del campo column9 . |
data_center_name |
principal.resource.name |
El valor se toma del campo data_center_name . |
datacenter.label |
security_result.detection_fields[].key |
El valor es datacenter label . |
datacenter.label |
security_result.detection_fields[].value |
El valor se toma del campo datacenter.label . |
destinationip |
target.asset.ip |
El valor se toma del campo destinationip . |
destinationip |
target.ip |
El valor se toma del campo destinationip . |
direction |
network.direction |
El valor se toma del campo direction y se convierte a mayúsculas. |
domain |
network.dns.questions[].name |
El valor se toma del campo domain y se elimina el punto final, si lo hay. |
dstPort |
target.port |
El valor se toma del campo dstPort . |
dstip |
target.asset.ip |
El valor se toma del campo dstip . |
dstip |
target.ip |
El valor se toma del campo dstip . |
egress.ip |
security_result.detection_fields[].key |
El valor es egress ip . |
egress.ip |
security_result.detection_fields[].value |
El valor se toma del campo egress.ip . |
egress.type |
security_result.detection_fields[].key |
El valor es egress type . |
egress.type |
security_result.detection_fields[].value |
El valor se toma del campo egress.type . |
externalip |
principal.asset.ip |
El valor se toma del campo externalip . |
externalip |
principal.ip |
El valor se toma del campo externalip . |
forwardingmethod |
additional.fields[].key |
El valor es forwardingmethod . |
forwardingmethod |
additional.fields[].value.string_value |
El valor se toma del campo forwardingmethod . |
granular_identity |
principal.user.user_display_name |
El valor se toma del campo granular_identity si están presentes tanto granular_identity como most_granular_identity . De lo contrario, se deriva del campo _policy_identity y se analiza más a fondo en función de identityType . |
granular_identity |
principal.user.email_addresses |
El valor se extrae del campo granular_identity mediante una expresión regular. |
granular_identity |
principal.user.first_name |
El valor se extrae del campo granular_identity mediante una expresión regular. |
granular_identity |
principal.user.last_name |
El valor se extrae del campo granular_identity mediante una expresión regular. |
granular_identity |
principal.user.userid |
El valor se extrae del campo granular_identity mediante una expresión regular. |
granular_identity |
principal.hostname |
El valor se toma del campo granular_identity . |
granular_identity |
principal.location.name |
El valor se toma del campo granular_identity . |
identity_types |
additional.fields[].value.string_value |
El valor se toma del campo identity_types . |
identities[] |
principal.user.product_object_id |
El valor se toma del campo identities[] . |
identities |
principal.user.product_object_id |
El valor se toma del campo identities . |
internalip |
principal.asset.ip |
El valor se toma del campo internalip . |
internalip |
principal.ip |
El valor se toma del campo internalip . |
isolated.fileaction |
security_result.detection_fields[].key |
El valor es isolated fileaction . |
isolated.fileaction |
security_result.detection_fields[].value |
El valor se toma del campo isolated.fileaction . |
isolated.state |
security_result.detection_fields[].key |
El valor es isolated state . |
isolated.state |
security_result.detection_fields[].value |
El valor se toma del campo isolated.state . |
most_granular_identity |
principal.user.identityType |
El valor se toma del campo most_granular_identity si están presentes tanto granular_identity como most_granular_identity . De lo contrario, se tomará del campo _policy_identity_type . |
nat_destination_ip |
principal.asset.ip |
El valor se toma del campo nat_destination_ip . |
nat_destination_ip |
principal.ip |
El valor se toma del campo nat_destination_ip . |
odns_categories |
security_result.category_details |
El valor se toma del campo odns_categories . |
policy.ruleid |
security_result.rule_id |
El valor se toma del campo policy.ruleid . |
policy.rulesetid |
security_result.detection_fields[].key |
El valor es rulesetid . |
policy.rulesetid |
security_result.detection_fields[].value |
El valor se toma del campo policy.rulesetid . |
policy.timebasedrule |
security_result.detection_fields[].key |
El valor es timebasedrule . |
policy.timebasedrule |
security_result.detection_fields[].value |
El valor se toma del campo policy.timebasedrule . |
port |
target.port |
El valor se toma del campo port . |
query_type_name |
network.dns.questions[].type |
La parte numérica se extrae del campo query_type_name mediante una expresión regular y se convierte en un número entero. |
query_type_name |
additional.fields[].value.string_value |
La parte de la cadena entre paréntesis se extrae del campo query_type_name mediante una expresión regular. |
querytype |
network.dns.questions[].type |
El valor se toma del campo querytype y se asigna a un valor numérico en función del tipo de registro DNS. |
referer |
network.http.referral_url |
El valor se toma del campo referer . |
requestmethod |
network.http.method |
El valor se toma del campo requestmethod . |
requestsize |
network.sent_bytes |
El valor se toma del campo requestsize y se convierte en un número entero sin signo. |
response |
additional.fields[].value.string_value |
El valor se toma del campo response . |
responsecode |
network.http.response_code |
El valor se toma del campo responsecode . |
responsefilename |
target.file.names |
El valor se toma del campo responsefilename . |
responsesize |
network.received_bytes |
El valor se toma del campo responsesize y se convierte en un número entero sin signo. |
returncode |
network.dns.response_code |
El valor se toma del campo returncode y se convierte en un número entero sin signo. |
securityoverridden |
additional.fields[].key |
El valor es securityoverridden . |
securityoverridden |
additional.fields[].value.string_value |
El valor se toma del campo securityoverridden . |
sha256 |
target.file.sha256 |
El valor se toma del campo sha256 . |
source_ip |
principal.asset.ip |
El valor se toma del campo source_ip si existe en los registros JSON o de column3 en los registros CSV. |
source_ip |
principal.ip |
El valor se toma del campo source_ip si existe en los registros JSON o de column3 en los registros CSV. |
srcPort |
principal.port |
El valor se toma del campo srcPort . |
statuscode |
network.http.response_code |
El valor se toma del campo statuscode . |
tenantcontrols |
additional.fields[].key |
El valor es tenantcontrols . |
tenantcontrols |
additional.fields[].value.string_value |
El valor se toma del campo tenantcontrols . |
timestamp |
metadata.event_timestamp.seconds |
El valor se analiza a partir del campo timestamp como una marca de tiempo. |
tunnel_name |
additional.fields[].key |
El valor es tunnel_name . |
tunnel_name |
additional.fields[].value.string_value |
El valor se toma del campo tunnel_name . |
tunnel_type |
metadata.product_event_type |
El valor se toma del campo tunnel_type . |
type |
additional.fields[].key |
El valor es type . |
type |
additional.fields[].value.string_value |
El valor se toma del campo type . |
url |
target.url |
El valor se toma del campo url . |
useragent |
network.http.user_agent |
El valor se toma del campo useragent . |
verdict |
security_result.action_details |
El valor se toma del campo verdict . |
warnstatus |
security_result.detection_fields[].key |
El valor es warnstatus . |
warnstatus |
security_result.detection_fields[].value |
El valor se toma del campo warnstatus . El valor es DNS Lookup Type . La parte de la cadena entre paréntesis se extrae del campo query_type_name mediante una expresión regular o es una cadena vacía si el campo no está presente. El valor se DNS request and response were made. determina en función de la presencia de determinados campos: NETWORK_DNS si question.name está presente, NETWORK_CONNECTION si están presentes principal.ip y target.ip , STATUS_UPDATE si solo está presente principal.ip o GENERIC_EVENT en los demás casos. El valor es UMBRELLA_DNS . El valor es Umbrella DNS . El valor es Cisco . El valor se asigna inicialmente a DNS . Si requestmethod es un método HTTP válido, se cambia a HTTP . La parte numérica se extrae del campo query_type_name mediante una expresión regular y se convierte en un número entero, o bien se deriva del campo querytype y se asigna a un valor numérico en función del tipo de registro DNS. El valor se deriva del campo useragent o column10 mediante el filtro parseduseragent . El valor se toma de la última parte del campo column3 después de dividirlo por comas. Si el campo no está presente, se trata de una cadena vacía. El valor se toma de la primera parte del campo column3 después de dividirlo por comas, o bien se toma del campo column2 si column3 no está presente. El valor se extrae del campo column2 o column3 mediante una expresión regular. El valor se extrae del campo column2 o column3 mediante una expresión regular. El valor se extrae del campo column2 o column3 mediante una expresión regular. El valor se extrae del campo column2 o column3 mediante una expresión regular. El valor se deriva de los campos action , column6 , column7 o verdict y se convierte a mayúsculas (ALLOW o BLOCK). El valor se establece en NETWORK_MALICIOUS si _categories contiene Malware o en NETWORK_SUSPICIOUS si _categories contiene Potentially Harmful . |
¿Necesitas más ayuda? Recibe respuestas de los miembros de la comunidad y de los profesionales de Google SecOps.