Recoger registros de auditoría de Oracle Cloud Infrastructure
En este documento se explica cómo ingerir registros de auditoría de Oracle Cloud Infrastructure en Google Security Operations mediante Amazon S3.
Antes de empezar
Asegúrate de que cumples los siguientes requisitos previos:
- Instancia de Google SecOps.
- Una cuenta de Oracle Cloud Infrastructure con permisos para crear y gestionar lo siguiente:
- Service Connector Hub
- Funciones de Oracle
- Bóvedas y secretos
- Grupos dinámicos y políticas de gestión de identidades y accesos
- Almacenamiento de registros
- Cuenta de AWS con permisos para crear y gestionar lo siguiente:
- Segmentos de S3
- Usuarios y políticas de gestión de identidades y accesos
Crear un segmento de Amazon S3
- Inicia sesión en la consola de administración de AWS.
- Ve a S3 > Crear segmento.
- Proporcione los siguientes detalles de configuración:
- Nombre del contenedor: escriba un nombre único (por ejemplo,
oci-audit-logs-bucket). - Región de AWS: selecciona una región (por ejemplo,
us-east-1). - Mantén la configuración predeterminada de las demás opciones.
- Nombre del contenedor: escriba un nombre único (por ejemplo,
- Haz clic en Crear segmento.
- Guarda el Nombre y la Región del bucket para usarlos más adelante.
Crear un usuario de gestión de identidades y accesos en AWS para OCI Functions
- Inicia sesión en la consola de administración de AWS.
- Ve a Gestión de identidades y accesos > Usuarios > Añadir usuarios.
- Proporcione los siguientes detalles de configuración:
- Nombre de usuario: introduce un nombre de usuario (por ejemplo,
oci-functions-s3-user). - Tipo de acceso: selecciona Clave de acceso - Acceso programático.
- Nombre de usuario: introduce un nombre de usuario (por ejemplo,
- Haz clic en Siguiente: Permisos.
- Haz clic en Adjuntar políticas directamente.
- Busca y selecciona la política AmazonS3FullAccess.
- Haz clic en Siguiente: Etiquetas.
- Haz clic en Siguiente: Revisar.
- Haz clic en Crear usuario.
- Importante: En la página de confirmación, copie y guarde las siguientes credenciales:
- ID de clave de acceso
- Clave de acceso secreta
Almacenar credenciales de AWS en OCI Vault
Para almacenar de forma segura las credenciales de AWS, debe usar Oracle Cloud Infrastructure Vault en lugar de codificarlas en el código de la función.
Crear un Vault y una clave de cifrado maestra
- Inicia sesión en la consola de Oracle Cloud.
- Ve a Identidad y seguridad > Bóveda.
- Si no tienes ninguna, haz clic en Crear Vault.
- Proporcione los siguientes detalles de configuración:
- Crear en compartimento: selecciona el compartimento.
- Nombre: introduce un nombre (por ejemplo,
oci-functions-vault).
- Haz clic en Crear Vault.
- Una vez creado el archivo seguro, haz clic en su nombre para abrirlo.
- En Claves de cifrado maestras, haz clic en Crear clave.
- Proporcione los siguientes detalles de configuración:
- Modo de protección: software
- Nombre: introduce un nombre (por ejemplo,
oci-functions-key). - Forma de la clave: algoritmo: AES
- Forma de la clave: longitud: 256 bits
- Haz clic en Crear clave.
Crear secretos para las credenciales de AWS
- En Protección con contraseña, en Secretos, haz clic en Crear secreto.
- Proporcione los siguientes detalles de configuración de la clave de acceso de AWS:
- Crear en compartimento: selecciona el compartimento.
- Nombre:
aws-access-key - Descripción: clave de acceso de AWS para S3
- Clave de cifrado: selecciona la clave de cifrado maestra que has creado.
- Contenido del tipo de secreto: texto sin formato
- Contenido secreto: pega tu ID de clave de acceso de AWS.
- Haz clic en Crear secreto.
- Copia y guarda el OCID de este secreto (tiene un aspecto similar a
ocid1.vaultsecret.oc1...). - Vuelve a hacer clic en Crear secreto para crear el segundo secreto.
- Proporcione los siguientes detalles de configuración de la clave secreta de AWS:
- Crear en compartimento: selecciona el compartimento.
- Nombre:
aws-secret-key - Descripción: clave secreta de AWS para S3
- Clave de cifrado: selecciona la misma clave de cifrado maestra.
- Contenido del tipo de secreto: texto sin formato
- Contenido secreto: pega tu clave de acceso secreta de AWS.
- Haz clic en Crear secreto.
- Copia y guarda el OCID de este secreto.
Crear un grupo dinámico para funciones de OCI
- Inicia sesión en la consola de Oracle Cloud.
- Ve a Identidad y seguridad > Identidad > Grupos dinámicos.
- Haz clic en Crear grupo dinámico.
Proporciona los siguientes detalles de configuración:
- Nombre:
oci-functions-dynamic-group - Descripción: grupo dinámico para que las funciones de OCI accedan a los secretos de Vault
Reglas coincidentes: introduzca la siguiente regla (sustituya
<your_compartment_ocid>por el OCID de su compartimento):ALL {resource.type = 'fnfunc', resource.compartment.id = '<your_compartment_ocid>'}
- Nombre:
Haz clic en Crear.
Crear una política de gestión de identidades y accesos para acceder a Vault
- Inicia sesión en la consola de Oracle Cloud.
- Ve a Identidad y seguridad > Identidad > Políticas.
- Seleccione el compartimento en el que quiera crear la política.
- Haz clic enCreate Policy (Crear política).
Proporciona los siguientes detalles de configuración:
- Nombre:
oci-functions-vault-access-policy - Descripción: permite que las funciones de OCI lean secretos de Vault.
- Creador de políticas: activa Mostrar editor manual.
Declaraciones de la política: introduce lo siguiente (sustituye
<compartment_name>por el nombre de tu compartimento):allow dynamic-group oci-functions-dynamic-group to manage secret-family in compartment <compartment_name>
- Nombre:
Haz clic en Crear.
Crear una aplicación de funciones de OCI
- Inicia sesión en la consola de Oracle Cloud.
- Ve a Servicios para desarrolladores > Aplicaciones (en Funciones).
- Haz clic en Crear aplicación.
- Proporcione los siguientes detalles de configuración:
- Nombre: introduce un nombre (por ejemplo,
oci-logs-to-s3-app). - VCN: seleccione una VCN en su compartimento.
- Subredes: selecciona una o varias subredes.
- Nombre: introduce un nombre (por ejemplo,
- Haz clic en Crear.
Crear y desplegar la función de OCI
Configurar Cloud Shell (opción recomendada)
- En la consola de Oracle Cloud, haga clic en el icono Cloud Shell, situado en la esquina superior derecha.
- Espera a que se inicialice Cloud Shell.
Crear la función
En Cloud Shell, crea un directorio para tu función:
mkdir pushlogs cd pushlogsInicializa una función de Python:
fn init --runtime pythonSe crearán tres archivos:
func.py,func.yamlyrequirements.txt.
Actualizar func.py
Sustituye el contenido de
func.pypor el siguiente código:import io import json import logging import boto3 import oci import base64 import os from fdk import response def handler(ctx, data: io.BytesIO = None): """ OCI Function to push audit logs from OCI Logging to AWS S3 """ try: # Parse incoming log data from Service Connector funDataStr = data.read().decode('utf-8') funData = json.loads(funDataStr) logging.getLogger().info(f"Received {len(funData)} log entries") # Replace these with your actual OCI Vault secret OCIDs secret_key_id = "ocid1.vaultsecret.oc1..<your_secret_key_ocid>" access_key_id = "ocid1.vaultsecret.oc1..<your_access_key_ocid>" # Replace with your S3 bucket name s3_bucket_name = "oci-audit-logs-bucket" # Use Resource Principals for OCI authentication signer = oci.auth.signers.get_resource_principals_signer() secret_client = oci.secrets.SecretsClient({}, signer=signer) def read_secret_value(secret_client, secret_id): """Retrieve and decode secret value from OCI Vault""" response = secret_client.get_secret_bundle(secret_id) base64_secret_content = response.data.secret_bundle_content.content base64_secret_bytes = base64_secret_content.encode('ascii') base64_message_bytes = base64.b64decode(base64_secret_bytes) secret_content = base64_message_bytes.decode('ascii') return secret_content # Retrieve AWS credentials from OCI Vault awsaccesskey = read_secret_value(secret_client, access_key_id) awssecretkey = read_secret_value(secret_client, secret_key_id) # Initialize boto3 session with AWS credentials session = boto3.Session( aws_access_key_id=awsaccesskey, aws_secret_access_key=awssecretkey ) s3 = session.resource('s3') # Process each log entry for i in range(0, len(funData)): # Use timestamp as filename filename = funData[i].get('time', f'log_{i}') # Remove special characters from filename filename = filename.replace(':', '-').replace('.', '-') logging.getLogger().info(f"Processing log entry: {filename}") # Write log entry to temporary file temp_file = f'/tmp/{filename}.json' with open(temp_file, 'w', encoding='utf-8') as f: json.dump(funData[i], f, ensure_ascii=False, indent=4) # Upload to S3 s3_key = f'{filename}.json' s3.meta.client.upload_file( Filename=temp_file, Bucket=s3_bucket_name, Key=s3_key ) logging.getLogger().info(f"Uploaded {s3_key} to S3 bucket {s3_bucket_name}") # Clean up temporary file os.remove(temp_file) return response.Response( ctx, response_data=json.dumps({ "status": "success", "processed_logs": len(funData) }), headers={"Content-Type": "application/json"} ) except Exception as e: logging.getLogger().error(f"Error processing logs: {str(e)}") return response.Response( ctx, response_data=json.dumps({ "status": "error", "message": str(e) }), headers={"Content-Type": "application/json"}, status_code=500 )- Sustituye
secret_key_idpor el OCID del secreto de tu vault para la clave secreta de AWS. - Sustituye
access_key_idpor el OCID del secreto de tu vault para la clave de acceso de AWS. - Sustituye
s3_bucket_namepor el nombre de tu segmento de S3.
- Sustituye
Actualiza func.yaml
Sustituye el contenido de func.yaml por lo siguiente:
schema_version: 20180708
name: pushlogs
version: 0.0.1
runtime: python
build_image: fnproject/python:3.9-dev
run_image: fnproject/python:3.9
entrypoint: /python/bin/fdk /function/func.py handler
memory: 256
Actualizar requirements.txt
Sustituye el contenido de
requirements.txtpor lo siguiente:fdk>=0.1.56 boto3 oci
Desplegar la función
Define el contexto de Fn para usar tu aplicación:
fn use context <region-context> fn update context oracle.compartment-id <compartment-ocid>Despliega la función:
fn -v deploy --app oci-logs-to-s3-appEspera a que se complete la implementación. Debería ver un resultado que indique que la función se ha desplegado correctamente.
Comprueba que se haya creado la función:
fn list functions oci-logs-to-s3-app
Crea un conector de servicio para enviar registros de auditoría de OCI a la función
- Inicia sesión en la consola de Oracle Cloud.
- Vaya a Analytics & AI > Mensajería > Service Connector Hub.
- Seleccione el compartimento en el que quiera crear el conector de servicio.
- Haz clic en Create Service Connector (Crear conector de servicio).
Configurar los detalles del conector de servicio
- Proporciona los siguientes detalles de configuración:
Información del conector de servicio:
* Nombre del conector: introduce un nombre descriptivo (por ejemplo, audit-logs-to-s3-connector).
* Descripción: descripción opcional (por ejemplo, "Reenviar registros de auditoría de OCI a AWS S3").
* Compartimento de recursos: seleccione el compartimento.
Configurar origen
- En Configurar fuente:
- Fuente: selecciona Logging.
- Compartimento: selecciona el compartimento que contiene los registros de auditoría.
- Grupo de registros: selecciona
_Audit(es el grupo de registros predeterminado de los registros de auditoría). - Registros: haz clic en + Otro registro.
- Selecciona el registro de auditoría de tu compartimento (por ejemplo,
_Audit_Include_Subcompartment).
Configurar destino
- En Configurar objetivo:
- Objetivo: selecciona Funciones.
- Compartment: selecciona el compartimento que contiene tu aplicación de función.
- Aplicación de función: selecciona
oci-logs-to-s3-app(la aplicación que has creado antes). - Función: selecciona
pushlogs(la función que has implementado).
Configurar política
En Configurar política, haz lo siguiente:
- Revisa las instrucciones de la política de gestión de identidades y accesos que se muestran.
- Haz clic en Crear para crear las políticas necesarias automáticamente.
Haz clic en Crear para crear el conector de servicio.
Espera a que se cree y se active el conector de servicio. El estado debería cambiar a Activo.
Verificar que los registros se envían a AWS S3
- Inicia sesión en la consola de Oracle Cloud.
- Realiza algunas acciones que generen registros de auditoría (por ejemplo, crea o modifica un recurso).
- Espera entre 2 y 5 minutos a que se procesen los registros.
- Inicia sesión en la consola de administración de AWS.
- Ve a S3 > Buckets.
- Haz clic en el segmento (por ejemplo,
oci-audit-logs-bucket). - Comprueba que los archivos de registro JSON aparezcan en el bucket.
Configurar un segmento de AWS S3 y IAM para Google SecOps
Crear un usuario de gestión de identidades y accesos para Chronicle
- Inicia sesión en la consola de administración de AWS.
- Ve a Gestión de identidades y accesos > Usuarios > Añadir usuarios.
- Proporcione los siguientes detalles de configuración:
- Nombre de usuario: introduce
chronicle-s3-reader. - Tipo de acceso: selecciona Clave de acceso - Acceso programático.
- Nombre de usuario: introduce
- Haz clic en Siguiente: Permisos.
- Haz clic en Adjuntar políticas directamente.
- Busca y selecciona la política AmazonS3ReadOnlyAccess.
- Haz clic en Siguiente: Etiquetas.
- Haz clic en Siguiente: Revisar.
- Haz clic en Crear usuario.
- Haz clic en Descargar archivo CSV para guardar el ID de clave de acceso y la clave de acceso secreta.
- Haz clic en Cerrar.
Opcional: Crea una política de gestión de identidades y accesos personalizada para aplicar el principio de mínimos privilegios
Si quieres restringir el acceso solo al grupo específico, sigue estos pasos:
- Ve a Gestión de identidades y accesos > Políticas > Crear política.
- Haz clic en la pestaña JSON.
Introduce la siguiente política:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::oci-audit-logs-bucket", "arn:aws:s3:::oci-audit-logs-bucket/*" ] } ] }- Sustituye
oci-audit-logs-bucketpor el nombre de tu segmento.
- Sustituye
Haz clic en Siguiente: Etiquetas.
Haz clic en Siguiente: Revisar.
Proporciona los siguientes detalles de configuración:
- Nombre:
chronicle-s3-read-policy - Descripción: acceso de solo lectura al cubo de registros de auditoría de OCI
- Nombre:
Haz clic en Crear política.
Vuelve a Gestión de identidades y accesos > Usuarios y selecciona el usuario
chronicle-s3-reader.Haz clic en Añadir permisos > Adjuntar políticas directamente.
Busca y selecciona
chronicle-s3-read-policy.Quita la política AmazonS3ReadOnlyAccess si la has añadido antes.
Haz clic en Añadir permisos.
Configurar un feed en Google SecOps para ingerir registros de auditoría de Oracle Cloud
- Ve a Configuración de SIEM > Feeds.
- Haz clic en Añadir nuevo feed.
- En la página siguiente, haga clic en Configurar un solo feed.
- En el campo Nombre del feed, introduce un nombre para el feed (por ejemplo,
Oracle Cloud Audit Logs). - Selecciona Amazon S3 V2 como Tipo de fuente.
- Seleccione Oracle Cloud Infrastructure como Tipo de registro.
- Haz clic en Siguiente.
- Especifique los valores de los siguientes parámetros de entrada:
- URI de S3: introduce el URI del contenedor de S3 (por ejemplo,
s3://oci-audit-logs-bucket/). - Opción de eliminación de la fuente: selecciona la opción de eliminación que prefieras:
- Nunca: se recomienda para las pruebas y la configuración inicial.
- Eliminar archivos transferidos: elimina los archivos después de que se hayan insertado correctamente (úsalo en producción para gestionar los costes de almacenamiento).
- 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: introduce el ID de clave de acceso del usuario de gestión de identidades y accesos de Chronicle que has creado.
- Clave de acceso secreta: introduce la clave de acceso secreta del usuario de gestión de identidades y accesos de Chronicle que has creado.
- Espacio de nombres de recursos: el espacio de nombres de recursos.
- Etiquetas de ingestión: etiqueta que se aplicará a los eventos de este feed.
- URI de S3: introduce el URI del contenedor de S3 (por ejemplo,
- Haz clic en Siguiente.
- Revise la configuración de su nuevo feed 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 |
|---|---|---|
data.request.headers.authorization.0 |
event.idm.read_only_udm.additional.fields |
Valor tomado de data.request.headers.authorization.0 y añadido como par clave-valor en el que la clave es "Request Headers Authorization". |
data.compartmentId |
event.idm.read_only_udm.additional.fields |
Valor tomado de data.compartmentId y añadido como par clave-valor en el que la clave es "compartmentId". |
data.compartmentName |
event.idm.read_only_udm.additional.fields |
Valor tomado de data.compartmentName y añadido como un par clave-valor en el que la clave es "compartmentName". |
data.response.headers.Content-Length.0 |
event.idm.read_only_udm.additional.fields |
Valor tomado de data.response.headers.Content-Length.0 y añadido como par clave-valor en el que la clave es "Response Headers Content-Length". |
data.response.headers.Content-Type.0 |
event.idm.read_only_udm.additional.fields |
Valor tomado de data.response.headers.Content-Type.0 y añadido como par clave-valor en el que la clave es "Response Headers Content-Type". |
data.eventGroupingId |
event.idm.read_only_udm.additional.fields |
Valor tomado de data.eventGroupingId y añadido como par clave-valor, donde la clave es "eventGroupingId". |
oracle.tenantid, data.identity.tenantId |
event.idm.read_only_udm.additional.fields |
El valor se toma de oracle.tenantid si está presente; de lo contrario, se toma de data.identity.tenantId. Se añade como un par clave-valor en el que la clave es "tenantId". |
data.message |
event.idm.read_only_udm.metadata.description |
Valor tomado de data.message. |
time |
event.idm.read_only_udm.metadata.event_timestamp |
Valor tomado de time y analizado como una marca de tiempo ISO8601. |
event.idm.read_only_udm.metadata.event_type |
El valor predeterminado es GENERIC_EVENT. Se define como NETWORK_CONNECTION si hay un principal (IP o nombre de host) y una IP de destino. Se define como STATUS_UPDATE si solo hay un principal. |
|
time |
event.idm.read_only_udm.metadata.ingested_timestamp |
Si oracle.ingestedtime no está vacío, el valor se toma del campo time y se analiza como una marca de tiempo ISO8601. |
oracle.tenantid |
event.idm.read_only_udm.metadata.product_deployment_id |
Valor tomado de oracle.tenantid. |
type |
event.idm.read_only_udm.metadata.product_event_type |
Valor tomado de type. |
oracle.logid |
event.idm.read_only_udm.metadata.product_log_id |
Valor tomado de oracle.logid. |
specversion |
event.idm.read_only_udm.metadata.product_version |
Valor tomado de specversion. |
data.request.action |
event.idm.read_only_udm.network.http.method |
Valor tomado de data.request.action. |
data.identity.userAgent |
event.idm.read_only_udm.network.http.parsed_user_agent |
Valor tomado de data.identity.userAgent y analizado. |
data.response.status |
event.idm.read_only_udm.network.http.response_code |
Valor tomado de data.response.status y convertido en un número entero. |
data.protocol |
event.idm.read_only_udm.network.ip_protocol |
El valor numérico de data.protocol se convierte en su representación de cadena (por ejemplo, 6 se convierte en "TCP" y 17 en "UDP"). |
data.bytesOut |
event.idm.read_only_udm.network.sent_bytes |
Valor tomado de data.bytesOut y convertido en un número entero sin signo. |
data.packets |
event.idm.read_only_udm.network.sent_packets |
Valor tomado de data.packets y convertido en un número entero. |
data.identity.consoleSessionId |
event.idm.read_only_udm.network.session_id |
Valor tomado de data.identity.consoleSessionId. |
id |
event.idm.read_only_udm.principal.asset.product_object_id |
Valor tomado de id. |
source |
event.idm.read_only_udm.principal.hostname |
Valor tomado de source. |
data.sourceAddress, data.identity.ipAddress |
event.idm.read_only_udm.principal.ip |
Los valores de data.sourceAddress y data.identity.ipAddress se combinan en este campo. |
data.sourcePort |
event.idm.read_only_udm.principal.port |
Valor tomado de data.sourcePort y convertido en un número entero. |
data.request.headers.X-Forwarded-For.0 |
event.idm.read_only_udm.principal.resource.attribute.labels |
Valor tomado de data.request.headers.X-Forwarded-For.0 y añadido como par clave-valor, donde la clave es "x forward". |
oracle.compartmentid |
event.idm.read_only_udm.principal.resource.attribute.labels |
Valor tomado de oracle.compartmentid y añadido como par clave-valor, donde la clave es "compartmentid". |
oracle.loggroupid |
event.idm.read_only_udm.principal.resource.attribute.labels |
Valor tomado de oracle.loggroupid y añadido como par clave-valor en el que la clave es "loggroupid". |
oracle.vniccompartmentocid |
event.idm.read_only_udm.principal.resource.attribute.labels |
Valor tomado de oracle.vniccompartmentocid y añadido como un par clave-valor en el que la clave es "vniccompartmentocid". |
oracle.vnicocid |
event.idm.read_only_udm.principal.resource.attribute.labels |
Valor tomado de oracle.vnicocid y añadido como par clave-valor en el que la clave es "vnicocid". |
oracle.vnicsubnetocid |
event.idm.read_only_udm.principal.resource.attribute.labels |
Valor tomado de oracle.vnicsubnetocid y añadido como par clave-valor en el que la clave es "vnicsubnetocid". |
data.flowid |
event.idm.read_only_udm.principal.resource.product_object_id |
Valor tomado de data.flowid. |
data.identity.credentials |
event.idm.read_only_udm.principal.user.attribute.labels |
Valor tomado de data.identity.credentials y añadido como par clave-valor en el que la clave es "credentials". |
data.identity.principalName |
event.idm.read_only_udm.principal.user.user_display_name |
Valor tomado de data.identity.principalName. |
data.identity.principalId |
event.idm.read_only_udm.principal.user.userid |
Valor tomado de data.identity.principalId. |
data.action |
event.idm.read_only_udm.security_result.action |
El valor predeterminado es UNKNOWN_ACTION. Si data.action es "REJECT", se le asigna el valor BLOCK. Si data.action es "ACCEPT", se le asigna el valor ALLOW. |
data.endTime |
event.idm.read_only_udm.security_result.detection_fields |
Valor tomado de data.endTime y añadido como par clave-valor en el que la clave es "endTime". |
data.startTime |
event.idm.read_only_udm.security_result.detection_fields |
Valor tomado de data.startTime y añadido como par clave-valor en el que la clave es "startTime". |
data.status |
event.idm.read_only_udm.security_result.detection_fields |
Valor tomado de data.status y añadido como par clave-valor en el que la clave es "status". |
data.version |
event.idm.read_only_udm.security_result.detection_fields |
Valor tomado de data.version y añadido como par clave-valor en el que la clave es "version". |
data.destinationAddress |
event.idm.read_only_udm.target.ip |
Valor tomado de data.destinationAddress. |
data.destinationPort |
event.idm.read_only_udm.target.port |
Valor tomado de data.destinationPort y convertido en un número entero. |
data.request.path |
event.idm.read_only_udm.target.url |
Valor tomado de data.request.path. |
event.idm.read_only_udm.metadata.product_name |
Definir como "ORACLE CLOUD AUDIT". | |
event.idm.read_only_udm.metadata.vendor_name |
Asigna el valor "ORACLE". |
¿Necesitas más ayuda? Recibe respuestas de los miembros de la comunidad y de los profesionales de Google SecOps.