Coletar registros do Druva Backup
Este documento explica como coletar registros do Druva Backup configurando uma função do Google Cloud Run que recupera eventos da API REST do Druva e os grava em um bucket do Google Cloud Storage. Em seguida, configure um feed do Google Security Operations usando o Google Cloud Storage V2.
A Druva é uma plataforma de proteção e gerenciamento de dados nativa da nuvem que oferece serviços de backup, recuperação de desastres e arquivamento para endpoints, aplicativos SaaS e cargas de trabalho empresariais. A plataforma gera trilhas de auditoria abrangentes, eventos de backup, atividades de restauração e alertas de segurança que podem ser integrados a soluções de SIEM para monitoramento e compliance.
Antes de começar
Verifique se você tem os pré-requisitos a seguir:
- Uma instância do Google SecOps
- Tenha um projeto do Google Cloud com o faturamento ativado.
- As seguintes APIs do Google Cloud estão ativadas:
- API Funções do Cloud Run
- API Cloud Scheduler
- API Cloud Storage
- API Pub/Sub
- API IAM
- Acesso do administrador do Druva Cloud ao console da plataforma Druva Cloud
- Acesso ao Centro de integração da Druva para criação de credenciais de API
Criar um bucket do Google Cloud Storage.
- Acesse o Console do Google Cloud.
- Selecione seu projeto ou crie um novo.
- No menu de navegação, acesse Cloud Storage > Buckets.
- Clique em Criar bucket.
Informe os seguintes detalhes de configuração:
Configuração Valor Nomeie seu bucket Insira um nome exclusivo globalmente, por exemplo, druva-backup-logs.Tipo de local Escolha com base nas suas necessidades (região, birregional, multirregional) Local Selecione o local mais próximo da sua instância do Google SecOps (por exemplo, us-central1).Classe de armazenamento Padrão (recomendado para registros acessados com frequência) Controle de acesso Uniforme (recomendado) Ferramentas de proteção Opcional: ativar o controle de versões de objetos ou a política de retenção Clique em Criar.
Coletar credenciais da API Druva
Para permitir que a função do Cloud Run recupere eventos do Druva, crie credenciais de API com autenticação OAuth 2.0.
Criar credenciais de API
- Faça login no Console da plataforma de nuvem da Druva (em inglês).
- No menu Navegação global, selecione Central de integração.
- No painel à esquerda, clique em Credenciais da API.
- Clique em New Credentials.
- Na janela Novas credenciais, forneça os seguintes detalhes:
Nome: insira um nome descritivo. Por exemplo,
Google SecOps Cloud Storage Integration. - Para aplicar restrições de autorização:
- Selecione Administrador da nuvem Druva para permitir acesso total à recuperação e modificação de dados.
- Se preferir, selecione Administrador do produto e escolha: Função de administrador do Cloud (somente leitura): para restringir o acesso apenas à recuperação de dados, sem direitos de modificação. Recomendado para integração com SIEM.
- Clique em Salvar.
Registrar credenciais de API
Depois de criar as credenciais da API, a janela Detalhes da credencial vai aparecer:
- Clique no ícone de cópia ao lado de ID do cliente para copiar o valor para a área de transferência.
- Salve o ID do cliente com segurança (por exemplo,
McNkxxxx4Vicxxxx4Ldpxxxx/09Uxxxx). - Clique no ícone de cópia ao lado de Chave secreta para copiar o valor para a área de transferência.
Salve a chave secreta com segurança (por exemplo,
Xmcxxxx8j5xxxx6NxxxxRbRxxxxNNyPt).
Criar uma conta de serviço
Crie uma conta de serviço dedicada para a função do Cloud Run acessar o Google Cloud Storage.
- No console do Google Cloud, acesse IAM e administrador > Contas de serviço.
- Clique em Criar conta de serviço.
- Informe os seguintes detalhes de configuração:
- Nome da conta de serviço: insira
druva-backup-function(ou um nome descritivo). - Descrição da conta de serviço: insira
Service account for Druva Backup Cloud Run function
- Nome da conta de serviço: insira
- Clique em Criar e continuar.
- Na seção Conceder acesso a essa conta de serviço ao projeto, adicione os seguintes papéis:
- Clique em Selecionar um papel e escolha Administrador de objetos do Storage.
- Clique em Adicionar outro papel e selecione Invocador do Cloud Run.
- Clique em Continuar.
- Clique em Concluído.
Registre o e-mail da conta de serviço (por exemplo,
druva-backup-function@PROJECT_ID.iam.gserviceaccount.com).
Criar um tópico do Pub/Sub
Crie um tópico do Pub/Sub que o Cloud Scheduler vai usar para acionar a função do Cloud Run.
- No console do Google Cloud, acesse Pub/Sub > Tópicos.
- Clique em Criar tópico.
- Informe os seguintes detalhes de configuração:
- ID do tópico: insira
druva-backup-trigger
- ID do tópico: insira
- Desmarque a opção Adicionar uma assinatura padrão.
Clique em Criar.
Criar a função do Cloud Run
Preparar o código da função
Crie uma função do Cloud Run que faça a autenticação com a API Druva usando credenciais de cliente OAuth 2.0, recupere eventos pelo endpoint de eventos com paginação e grave os resultados como NDJSON no bucket do GCS.
implantar a função do Cloud Run
- No console do Google Cloud, acesse Funções do Cloud Run.
- Clique em Criar função.
Informe os seguintes detalhes de configuração:
- Ambiente: selecione 2ª geração.
- Nome da função: insira
druva-backup-to-gcs. - Região: selecione a região mais próxima do seu bucket do GCS (por exemplo,
us-central1). - Tipo de gatilho: selecione Cloud Pub/Sub
- Tópico do Cloud Pub/Sub: selecione
druva-backup-trigger - Conta de serviço: selecione
druva-backup-function@PROJECT_ID.iam.gserviceaccount.com - Memória alocada:
512 MiB - Tempo limite:
540segundos - Número máximo de instâncias:
1
Clique em Próxima.
Selecione Python 3.11 como o Ambiente de execução.
Defina o Ponto de entrada como
main.No editor Código-fonte, substitua o conteúdo de
main.pypelo seguinte: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"Substitua os conteúdos de
requirements.txtpelo seguinte:requests>=2.31.0 google-cloud-storage>=2.14.0
Configure as variáveis de ambiente
- Na configuração da função do Cloud Run, acesse a seção Configurações de ambiente de execução, build, conexões e segurança.
Em Variáveis de ambiente de execução, adicione as seguintes variáveis:
GCS_BUCKET: o nome do bucket do GCS (por exemplo,druva-backup-logs)GCS_PREFIX: o caminho do prefixo para arquivos de registro (por exemplo,druva_backup)STATE_KEY: o nome do arquivo de estado (por exemplo,druva_state.json)DRUVA_BASE_URL: o URL base da API Druva:apis.druva.compara Druva Cloud (Standard)govcloudapis.druva.compara Druva GovCloud
CLIENT_ID: o ID do cliente das credenciais da API Druva.CLIENT_SECRET: a chave secreta das credenciais da API do DruvaMAX_RECORDS: número máximo de registros a serem buscados por invocação (por exemplo,10000)PAGE_SIZE: número de eventos por página da API (máximo de500)LOOKBACK_HOURS: número de horas para considerar na primeira execução (por exemplo,24)
Clique em Implantar.
Aguarde a conclusão da implantação.
Criar um job do Cloud Scheduler
Crie um job do Cloud Scheduler para acionar a função do Cloud Run em intervalos regulares.
- No console do Google Cloud, acesse o Cloud Scheduler.
- Clique em Criar job.
Informe os seguintes detalhes de configuração:
- Nome: insira
druva-backup-scheduler. - Região: selecione a mesma região da sua função do Cloud Run (por exemplo,
us-central1). - Descrição: insira
Triggers Druva Backup log collection every 30 minutes. - Frequência: insira
*/30 * * * *(a cada 30 minutos) - Fuso horário: selecione seu fuso horário preferido (por exemplo,
UTC).
- Nome: insira
Clique em Continuar.
Configure o destino:
- Tipo de destino: selecione Pub/Sub.
- Tópico do Cloud Pub/Sub: selecione
druva-backup-trigger - Corpo da mensagem: insira
{"trigger": "scheduled"}.
Clique em Criar.
Testar o job do Cloud Scheduler
- Na lista do Cloud Scheduler, localize
druva-backup-scheduler. - Clique em Forçar execução para acionar a função imediatamente.
- Verifique a execução conferindo:
- Os registros de funções do Cloud Run em Cloud Run functions > druva-backup-to-gcs > Registros
- O bucket do GCS para novos arquivos NDJSON em Cloud Storage > druva-backup-logs
Recuperar a conta de serviço do Google SecOps e configurar o feed
Receber o e-mail da conta de serviço
- Acesse Configurações do SIEM > Feeds.
- Clique em Adicionar novo feed.
- Clique em Configurar um único feed.
- No campo Nome do feed, insira um nome para o feed (por exemplo,
Druva Backup Events). - Selecione Google Cloud Storage V2 como o Tipo de origem.
- Selecione Druva Backup como o Tipo de registro.
Clique em Receber conta de serviço. Um e-mail exclusivo da conta de serviço será exibido, por exemplo:
chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.comCopie esse endereço de e-mail para usar na próxima etapa.
Configurar o feed
- Clique em Próxima.
Especifique valores para os seguintes parâmetros de entrada:
URL do bucket de armazenamento: insira o URI do bucket do GCS com o caminho do prefixo:
gs://druva-backup-logs/druva_backup/Opção de exclusão da fonte: selecione a opção de exclusão de acordo com sua preferência:
- Nunca: nunca exclui arquivos após as transferências (recomendado para testes)
- Excluir arquivos transferidos: exclui os arquivos após a transferência ser concluída.
- Excluir arquivos transferidos e diretórios vazios: exclui arquivos e diretórios vazios após a transferência bem-sucedida.
Idade máxima do arquivo: inclui arquivos modificados nos últimos dias. O padrão é 180 dias.
Namespace do recurso: o namespace do recurso
Rótulos de ingestão: o rótulo a ser aplicado aos eventos deste feed
Clique em Próxima.
Revise a nova configuração do feed na tela Finalizar e clique em Enviar.
Conceder permissões do IAM à conta de serviço do Google SecOps
A conta de serviço do Google SecOps precisa da função Leitor de objetos do Storage no seu bucket do GCS para ler os arquivos de registro gravados pela função do Cloud Run.
- Acesse Cloud Storage > Buckets.
- Clique no nome do bucket (por exemplo,
druva-backup-logs). - Acesse a guia Permissões.
- Clique em Conceder acesso.
- Informe os seguintes detalhes de configuração:
- Adicionar participantes: cole o e-mail da conta de serviço do Google SecOps (por exemplo,
chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com). - Atribuir papéis: selecione Leitor de objetos do Storage.
- Adicionar participantes: cole o e-mail da conta de serviço do Google SecOps (por exemplo,
Clique em Salvar.
Tabela de mapeamento do UDM
| Campo de registro | Mapeamento do UDM | Lógica |
|---|---|---|
| inSyncUserID, eventsGroupId, FilesMissed, FilesBackedup, TotalBackupSize, TotalBytesTransferred, facility, inSyncDataSourceID, initiator, event_type | additional.fields | Mesclado com rótulos criados em cada campo, se não estiver vazio |
| iniciador | extensions.auth.type | Definido como "AUTHTYPE_UNSPECIFIED" se o iniciador corresponder à regex de e-mail |
| metadata.event_type | Definido como "USER_LOGIN" se has_target_user for verdadeiro e has_principal for verdadeiro; "STATUS_UPDATE" se has_principal for verdadeiro e has_target for falso; caso contrário, "GENERIC_EVENT" | |
| eventID | metadata.product_log_id | Convertido em string |
| metadata.product_name | Definido como "DRUVA_BACKUP" | |
| clientVersion | metadata.product_version | Valor copiado diretamente |
| inSyncDataSourceName | principal.asset.hostname | Valor copiado diretamente |
| ip | principal.asset.ip | Mesclado do IP |
| inSyncDataSourceName | principal.hostname | Valor copiado diretamente |
| ip | principal.ip | Mesclado do IP |
| clientOS | principal.platform | Definido como "LINUX" se corresponder a (?i)Linux; "WINDOWS" se corresponder a (?i)windows; "MAC" se corresponder a (?i)mac |
| profileName | principal.resource.name | Valor copiado diretamente |
| profileID | principal.resource.product_object_id | Convertido em string |
| eventState | security_result.action | Definido como "ALLOW" se corresponder a (?i)Success, caso contrário, "BLOCK" |
| eventState | security_result.action_details | Valor copiado diretamente |
| gravidade, | security_result.severity | Definido como "LOW" se estiver em [0,1,2,3,LOW]; "MEDIUM" se estiver em [4,5,6,MEDIUM,SUBSTANTIAL,INFO]; "HIGH" se estiver em [7,8,HIGH,SEVERE]; "CRITICAL" se estiver em [9,10,VERY-HIGH,CRITICAL] |
| inSyncUserEmail, iniciador | target.user.email_addresses | Unido de inSyncUserEmail; também do iniciador se corresponder à regex de e-mail |
| inSyncUserName | target.user.userid | Valor copiado diretamente |
| metadata.vendor_name | Definido como "DRUVA_BACKUP" |
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.