Recopila registros de Druva Backup
En este documento, se explica cómo recopilar registros de Druva Backup configurando una función de Google Cloud Run que recupera eventos de la API de REST de Druva y los escribe en un bucket de Google Cloud Storage, y, luego, configurando un feed de Google Security Operations con Google Cloud Storage V2.
Druva es una plataforma de administración y protección de datos nativa de la nube que proporciona servicios de copia de seguridad, recuperación ante desastres y archivo para endpoints, aplicaciones de SaaS y cargas de trabajo empresariales. La plataforma genera registros de auditoría integrales, eventos de copias de seguridad, actividades de restablecimiento y alertas de seguridad que se pueden integrar con soluciones de SIEM para la supervisión y el cumplimiento.
Antes de comenzar
Asegúrate de cumplir con los siguientes requisitos previos:
- Una instancia de Google SecOps
- Un proyecto de Google Cloud con la facturación habilitada.
- Se habilitaron las siguientes APIs de Google Cloud:
- API de funciones de Cloud Run
- API de Cloud Scheduler
- API de Cloud Storage
- API de Pub/Sub
- API de IAM
- Acceso de administrador de Druva Cloud a la consola de Druva Cloud Platform
- Acceso al Centro de integración de Druva para la creación de credenciales de API
Crear un bucket de Google Cloud Storage
- Ve a la consola de Google Cloud.
- Selecciona tu proyecto o crea uno nuevo.
- En el menú de navegación, ve a Cloud Storage > Buckets.
- Haz clic en Crear bucket.
Proporciona los siguientes detalles de configuración:
Configuración Valor Asigna un nombre a tu bucket Ingresa un nombre global único (por ejemplo, druva-backup-logs).Tipo de ubicación Elige según tus necesidades (región, birregional, multirregional) Ubicación Selecciona la ubicación más cercana a tu instancia de Google SecOps (por ejemplo, us-central1).Clase de almacenamiento Estándar (recomendado para los registros a los que se accede con frecuencia) Control de acceso Uniforme (recomendado) Herramientas de protección Opcional: Habilita el control de versiones de objetos o la política de retención Haz clic en Crear.
Recopila las credenciales de la API de Druva
Para permitir que la función de Cloud Run recupere eventos de Druva, debes crear credenciales de API con autenticación de OAuth 2.0.
Crea credenciales de API
- Accede a la consola de Druva Cloud Platform.
- En el menú de Navegación global, selecciona Centro de integración.
- En el panel izquierdo, haz clic en Credenciales de API.
- Haz clic en New Credentials.
- En la ventana New Credentials, proporciona los siguientes detalles:
Name: Ingresa un nombre descriptivo (por ejemplo,
Google SecOps Cloud Storage Integration). - Para aplicar restricciones de autorización, haz lo siguiente:
- Selecciona Administrador de Druva Cloud para permitir el acceso completo a la recuperación y modificación de datos.
- También puedes seleccionar Administrador de productos y elegir una de las siguientes opciones: Rol de administrador de Cloud (solo lectura): Para restringir el acceso solo a la recuperación de datos sin derechos de modificación (se recomienda para la integración de SIEM)
- Haz clic en Guardar.
Registra las credenciales de la API
Después de crear las credenciales de la API, aparecerá la ventana Detalles de la credencial:
- Haz clic en el ícono de copiar junto a ID de cliente para copiar el valor en el portapapeles.
- Guarda el ID de cliente de forma segura (por ejemplo,
McNkxxxx4Vicxxxx4Ldpxxxx/09Uxxxx). - Haz clic en el ícono de copiar junto a Clave secreta para copiar el valor en el portapapeles.
Guarda la clave secreta de forma segura (por ejemplo,
Xmcxxxx8j5xxxx6NxxxxRbRxxxxNNyPt).
Crea una cuenta de servicio
Crea una cuenta de servicio dedicada para que la función de Cloud Run acceda a Google Cloud Storage.
- En la consola de Google Cloud, ve a IAM y administración > Cuentas de servicio.
- Haz clic en Crear cuenta de servicio.
- Proporciona los siguientes detalles de configuración:
- Nombre de la cuenta de servicio: Ingresa
druva-backup-function(o un nombre descriptivo). - Descripción de la cuenta de servicio: Ingresa
Service account for Druva Backup Cloud Run function.
- Nombre de la cuenta de servicio: Ingresa
- Haz clic en Crear y continuar.
- En la sección Otorga a esta cuenta de servicio acceso al proyecto, agrega los siguientes roles:
- Haz clic en Seleccionar un rol y, luego, selecciona Administrador de objetos de Storage.
- Haz clic en Agregar otro rol y selecciona Invocador de Cloud Run.
- Haz clic en Continuar.
- Haz clic en Listo.
Registra el correo electrónico de la cuenta de servicio (por ejemplo,
druva-backup-function@PROJECT_ID.iam.gserviceaccount.com).
Crea un tema de Pub/Sub
Crea un tema de Pub/Sub que Cloud Scheduler usará para activar la función de Cloud Run.
- En la consola de Google Cloud, ve a Pub/Sub > Temas.
- Haz clic en Crear tema.
- Proporciona los siguientes detalles de configuración:
- ID del tema: Ingresa
druva-backup-trigger.
- ID del tema: Ingresa
- Desmarca Agregar una suscripción predeterminada.
Haz clic en Crear.
Crea la función de Cloud Run
Prepara el código de la función
Crea una función de Cloud Run que se autentique con la API de Druva usando credenciales de cliente de OAuth 2.0, recupere eventos a través del extremo de eventos con paginación y escriba los resultados como NDJSON en el bucket de GCS.
Implementa la Cloud Run function
- En la consola de Google Cloud, ve a Cloud Run functions.
- Haz clic en Crear función.
Proporciona los siguientes detalles de configuración:
- Entorno: Selecciona 2ª gen..
- Nombre de la función: Ingresa
druva-backup-to-gcs. - Región: Selecciona la región más cercana a tu bucket de GCS (por ejemplo,
us-central1). - Tipo de activador: Selecciona Cloud Pub/Sub.
- Tema de Cloud Pub/Sub: Selecciona
druva-backup-trigger. - Cuenta de servicio: Selecciona
druva-backup-function@PROJECT_ID.iam.gserviceaccount.com. - Memoria asignada:
512 MiB - Tiempo de espera:
540segundos - Cantidad máxima de instancias:
1
Haz clic en Siguiente.
Selecciona Python 3.11 como el Entorno de ejecución.
Establece el Punto de entrada en
main.En el editor de código fuente, reemplaza el contenido de
main.pypor lo siguiente:import base64 import json import os import time from datetime import datetime, timezone, timedelta import requests from google.cloud import storage GCS_BUCKET = os.environ["GCS_BUCKET"] GCS_PREFIX = os.environ.get("GCS_PREFIX", "druva_backup") STATE_KEY = os.environ.get("STATE_KEY", "druva_state.json") DRUVA_BASE_URL = os.environ.get("DRUVA_BASE_URL", "apis.druva.com") CLIENT_ID = os.environ["CLIENT_ID"] CLIENT_SECRET = os.environ["CLIENT_SECRET"] MAX_RECORDS = int(os.environ.get("MAX_RECORDS", "10000")) PAGE_SIZE = int(os.environ.get("PAGE_SIZE", "500")) LOOKBACK_HOURS = int(os.environ.get("LOOKBACK_HOURS", "24")) def get_oauth_token(): """Obtain OAuth 2.0 access token using client credentials grant.""" token_url = f"https://{DRUVA_BASE_URL}/token" payload = { "grant_type": "client_credentials", "scope": "read", } resp = requests.post( token_url, data=payload, auth=(CLIENT_ID, CLIENT_SECRET), timeout=30, ) resp.raise_for_status() return resp.json()["access_token"] def load_state(storage_client): """Load the persisted state (last event time and tracker) from GCS.""" bucket = storage_client.bucket(GCS_BUCKET) blob = bucket.blob(f"{GCS_PREFIX}/{STATE_KEY}") if blob.exists(): return json.loads(blob.download_as_text()) return {} def save_state(storage_client, state): """Persist state to GCS.""" bucket = storage_client.bucket(GCS_BUCKET) blob = bucket.blob(f"{GCS_PREFIX}/{STATE_KEY}") blob.upload_from_string( json.dumps(state), content_type="application/json", ) def fetch_events(token, state): """Fetch events from Druva API with pagination via nextPageToken.""" events_url = f"https://{DRUVA_BASE_URL}/insync/eventmanagement/v2/events" headers = { "Authorization": f"Bearer {token}", "Accept": "application/json", } params = {"pageSize": PAGE_SIZE} tracker = state.get("tracker") last_event_time = state.get("last_event_time") if tracker: params["tracker"] = tracker elif last_event_time: params["fromTime"] = last_event_time else: lookback = datetime.now(timezone.utc) - timedelta(hours=LOOKBACK_HOURS) params["fromTime"] = lookback.strftime("%Y-%m-%dT%H:%M:%SZ") all_events = [] total_fetched = 0 while total_fetched < MAX_RECORDS: resp = requests.get( events_url, headers=headers, params=params, timeout=60, ) resp.raise_for_status() data = resp.json() events = data.get("events", []) all_events.extend(events) total_fetched += len(events) new_tracker = data.get("tracker") next_page_token = data.get("nextPageToken") if new_tracker: state["tracker"] = new_tracker if next_page_token: params["nextPageToken"] = next_page_token params.pop("tracker", None) params.pop("fromTime", None) else: break if all_events: last_ts = all_events[-1].get("eventTime", "") if last_ts: state["last_event_time"] = last_ts return all_events, state def write_events_to_gcs(storage_client, events): """Write events as NDJSON to GCS.""" if not events: return now = datetime.now(timezone.utc) filename = now.strftime("%Y%m%d_%H%M%S") + ".ndjson" blob_path = f"{GCS_PREFIX}/{now.strftime('%Y/%m/%d')}/{filename}" ndjson_lines = "\n".join(json.dumps(event) for event in events) bucket = storage_client.bucket(GCS_BUCKET) blob = bucket.blob(blob_path) blob.upload_from_string( ndjson_lines, content_type="application/x-ndjson", ) print(f"Wrote {len(events)} events to gs://{GCS_BUCKET}/{blob_path}") def main(event, context): """Cloud Run function entry point triggered by Pub/Sub.""" storage_client = storage.Client() token = get_oauth_token() state = load_state(storage_client) events, updated_state = fetch_events(token, state) write_events_to_gcs(storage_client, events) save_state(storage_client, updated_state) print(f"Completed: fetched {len(events)} events") return f"OK: {len(events)} events"Reemplaza el contenido de
requirements.txtpor lo siguiente:requests>=2.31.0 google-cloud-storage>=2.14.0
Configure las variables de entorno
- En la configuración de la función de Cloud Run, ve a la sección Configuración del entorno de ejecución, la compilación, las conexiones y la seguridad.
En Variables de entorno de ejecución, agrega las siguientes variables:
GCS_BUCKET: El nombre de tu bucket de GCS (por ejemplo,druva-backup-logs)GCS_PREFIX: Es la ruta de acceso del prefijo para los archivos de registro (por ejemplo,druva_backup).STATE_KEY: El nombre del archivo de estado (por ejemplo,druva_state.json)DRUVA_BASE_URL: URL base de la API de Druva:apis.druva.compara Druva Cloud (estándar)govcloudapis.druva.compara Druva GovCloud
CLIENT_ID: Es el ID de cliente de las credenciales de la API de Druva.CLIENT_SECRET: La clave secreta de las credenciales de la API de DruvaMAX_RECORDS: Cantidad máxima de registros que se recuperarán por invocación (por ejemplo,10000)PAGE_SIZE: Cantidad de eventos por página de la API (máximo500)LOOKBACK_HOURS: Cantidad de horas que se deben tener en cuenta en la primera ejecución (por ejemplo,24)
Haz clic en Implementar.
Espera a que se complete la implementación correctamente.
Crea un trabajo de Cloud Scheduler
Crea un trabajo de Cloud Scheduler para activar la función de Cloud Run a intervalos regulares.
- En la consola de Google Cloud, ve a Cloud Scheduler.
- Haz clic en Crear trabajo.
Proporciona los siguientes detalles de configuración:
- Nombre: Ingresa
druva-backup-scheduler. - Región: Selecciona la misma región que tu función de Cloud Run (por ejemplo,
us-central1). - Descripción: Ingresa
Triggers Druva Backup log collection every 30 minutes. - Frecuencia: Ingresa
*/30 * * * *(cada 30 minutos). - Zona horaria: Selecciona tu zona horaria preferida (por ejemplo,
UTC).
- Nombre: Ingresa
Haz clic en Continuar.
Configura el destino:
- Tipo de destino: Selecciona Pub/Sub.
- Tema de Cloud Pub/Sub: Selecciona
druva-backup-trigger. - Cuerpo del mensaje: Ingresa
{"trigger": "scheduled"}.
Haz clic en Crear.
Prueba el trabajo de Cloud Scheduler
- En la lista de Cloud Scheduler, busca
druva-backup-scheduler. - Haz clic en Forzar ejecución para activar la función de inmediato.
- Para verificar la ejecución, comprueba lo siguiente:
- Los registros de la función de Cloud Run en Cloud Run Functions > druva-backup-to-gcs > Registros
- El bucket de GCS para los archivos NDJSON nuevos en Cloud Storage > druva-backup-logs
Recupera la cuenta de servicio de Google SecOps y configura el feed
Obtén el correo electrónico de la cuenta de servicio
- Ve a Configuración de SIEM > Feeds.
- Haz clic en Agregar feed nuevo.
- Haz clic en Configura un feed único.
- En el campo Nombre del feed, ingresa un nombre para el feed (por ejemplo,
Druva Backup Events). - Selecciona Google Cloud Storage V2 como el Tipo de fuente.
- Selecciona Copia de seguridad de Druva como el Tipo de registro.
Haz clic en Obtener cuenta de servicio. Se mostrará un correo electrónico único de la cuenta de servicio, por ejemplo:
chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.comCopia esta dirección de correo electrónico para usarla en el siguiente paso.
Configura el feed
- Haz clic en Siguiente.
Especifica valores para los siguientes parámetros de entrada:
URL del bucket de almacenamiento: Ingresa el URI del bucket de GCS con la ruta de acceso del prefijo:
gs://druva-backup-logs/druva_backup/Opción de borrado de la fuente: Selecciona la opción de borrado según tu preferencia:
- Nunca: Nunca borra ningún archivo después de las transferencias (se recomienda para las pruebas)
- Borrar archivos transferidos: Borra los archivos después de una transferencia exitosa.
- Borrar los archivos transferidos y los directorios vacíos: Borra los archivos y los directorios vacíos después de la transferencia exitosa.
Antigüedad máxima del archivo: Incluye los archivos modificados en la cantidad de días más reciente (el valor predeterminado es 180 días).
Espacio de nombres del recurso: Es el espacio de nombres del recurso.
Etiquetas de transmisión: Es la etiqueta que se aplicará a los eventos de este feed.
Haz clic en Siguiente.
Revisa la nueva configuración del feed en la pantalla Finalizar y, luego, haz clic en Enviar.
Otorga permisos de IAM a la cuenta de servicio de Google SecOps
La cuenta de servicio de Google SecOps necesita el rol de Visualizador de objetos de Storage en tu bucket de GCS para leer los archivos de registro que escribe la función de Cloud Run.
- Ve a Cloud Storage > Buckets.
- Haz clic en el nombre de tu bucket (por ejemplo,
druva-backup-logs). - Ve a la pestaña Permisos.
- Haz clic en Otorgar acceso.
- Proporciona los siguientes detalles de configuración:
- Agregar principales: Pega el correo electrónico de la cuenta de servicio de Google SecOps (por ejemplo,
chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com). - Asignar roles: Selecciona Visualizador de objetos de Storage.
- Agregar principales: Pega el correo electrónico de la cuenta de servicio de Google SecOps (por ejemplo,
Haz clic en Guardar.
Tabla de asignación de UDM
| Campo de registro | Asignación de UDM | Lógica |
|---|---|---|
| inSyncUserID, eventsGroupId, FilesMissed, FilesBackedup, TotalBackupSize, TotalBytesTransferred, facility, inSyncDataSourceID, initiator, event_type | additional.fields | Se combina con las etiquetas creadas a partir de cada campo si no está vacío. |
| iniciador | extensions.auth.type | Se establece en "AUTHTYPE_UNSPECIFIED" si el iniciador coincide con la regex de correo electrónico. |
| metadata.event_type | Se establece en "USER_LOGIN" si has_target_user es verdadero y has_principal es verdadero; en "STATUS_UPDATE" si has_principal es verdadero y has_target es falso; de lo contrario, se establece en "GENERIC_EVENT". | |
| eventID | metadata.product_log_id | Se convirtió en cadena |
| metadata.product_name | Se establece en "DRUVA_BACKUP". | |
| clientVersion | metadata.product_version | Valor copiado directamente |
| inSyncDataSourceName | principal.asset.hostname | Valor copiado directamente |
| ip | principal.asset.ip | Se combinó desde la IP |
| inSyncDataSourceName | principal.hostname | Valor copiado directamente |
| ip | principal.ip | Se combinó desde la IP |
| clientOS | principal.platform | Se establece en "LINUX" si coincide con (?i)Linux; en "WINDOWS" si coincide con (?i)windows; en "MAC" si coincide con (?i)mac. |
| profileName | principal.resource.name | Valor copiado directamente |
| profileID | principal.resource.product_object_id | Se convirtió en cadena |
| eventState | security_result.action | Se establece en "ALLOW" si coincide con (?i)Success; de lo contrario, se establece en "BLOCK". |
| eventState | security_result.action_details | Valor copiado directamente |
| gravedad, | security_result.severity | Se establece en "LOW" si está en [0,1,2,3,LOW]; "MEDIUM" si está en [4,5,6,MEDIUM,SUBSTANTIAL,INFO]; "HIGH" si está en [7,8,HIGH,SEVERE]; "CRITICAL" si está en [9,10,VERY-HIGH,CRITICAL] |
| inSyncUserEmail, iniciador | target.user.email_addresses | Se fusionó de inSyncUserEmail; también del iniciador si coincide con la regex de correo electrónico |
| inSyncUserName | target.user.userid | Valor copiado directamente |
| metadata.vendor_name | Se establece en "DRUVA_BACKUP". |
¿Necesitas más ayuda? Obtén respuestas de miembros de la comunidad y profesionales de Google SecOps.