Coletar registros do Druva Backup

Compatível com:

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.

  1. Acesse o Console do Google Cloud.
  2. Selecione seu projeto ou crie um novo.
  3. No menu de navegação, acesse Cloud Storage > Buckets.
  4. Clique em Criar bucket.
  5. 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
  6. 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

  1. Faça login no Console da plataforma de nuvem da Druva (em inglês).
  2. No menu Navegação global, selecione Central de integração.
  3. No painel à esquerda, clique em Credenciais da API.
  4. Clique em New Credentials.
  5. Na janela Novas credenciais, forneça os seguintes detalhes: Nome: insira um nome descritivo. Por exemplo, Google SecOps Cloud Storage Integration.
  6. Para aplicar restrições de autorização:
    1. Selecione Administrador da nuvem Druva para permitir acesso total à recuperação e modificação de dados.
    2. 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.
  7. Clique em Salvar.

Registrar credenciais de API

Depois de criar as credenciais da API, a janela Detalhes da credencial vai aparecer:

  1. Clique no ícone de cópia ao lado de ID do cliente para copiar o valor para a área de transferência.
  2. Salve o ID do cliente com segurança (por exemplo, McNkxxxx4Vicxxxx4Ldpxxxx/09Uxxxx).
  3. Clique no ícone de cópia ao lado de Chave secreta para copiar o valor para a área de transferência.
  4. 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.

  1. No console do Google Cloud, acesse IAM e administrador > Contas de serviço.
  2. Clique em Criar conta de serviço.
  3. 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
  4. Clique em Criar e continuar.
  5. Na seção Conceder acesso a essa conta de serviço ao projeto, adicione os seguintes papéis:
    1. Clique em Selecionar um papel e escolha Administrador de objetos do Storage.
    2. Clique em Adicionar outro papel e selecione Invocador do Cloud Run.
  6. Clique em Continuar.
  7. Clique em Concluído.
  8. 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.

  1. No console do Google Cloud, acesse Pub/Sub > Tópicos.
  2. Clique em Criar tópico.
  3. Informe os seguintes detalhes de configuração:
    • ID do tópico: insira druva-backup-trigger
  4. Desmarque a opção Adicionar uma assinatura padrão.
  5. 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

  1. No console do Google Cloud, acesse Funções do Cloud Run.
  2. Clique em Criar função.
  3. 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: 540 segundos
    • Número máximo de instâncias: 1
  4. Clique em Próxima.

  5. Selecione Python 3.11 como o Ambiente de execução.

  6. Defina o Ponto de entrada como main.

  7. No editor Código-fonte, substitua o conteúdo de main.py pelo 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"
    
  8. Substitua os conteúdos de requirements.txt pelo seguinte:

    requests>=2.31.0
    google-cloud-storage>=2.14.0
    

Configure as variáveis de ambiente

  1. 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.
  2. 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.com para Druva Cloud (Standard)
      • govcloudapis.druva.com para Druva GovCloud
    • CLIENT_ID: o ID do cliente das credenciais da API Druva.
    • CLIENT_SECRET: a chave secreta das credenciais da API do Druva
    • MAX_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 de 500)
    • LOOKBACK_HOURS: número de horas para considerar na primeira execução (por exemplo, 24)
  3. Clique em Implantar.

  4. 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.

  1. No console do Google Cloud, acesse o Cloud Scheduler.
  2. Clique em Criar job.
  3. 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).
  4. Clique em Continuar.

  5. 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"}.
  6. Clique em Criar.

Testar o job do Cloud Scheduler

  1. Na lista do Cloud Scheduler, localize druva-backup-scheduler.
  2. Clique em Forçar execução para acionar a função imediatamente.
  3. 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

  1. Acesse Configurações do SIEM > Feeds.
  2. Clique em Adicionar novo feed.
  3. Clique em Configurar um único feed.
  4. No campo Nome do feed, insira um nome para o feed (por exemplo, Druva Backup Events).
  5. Selecione Google Cloud Storage V2 como o Tipo de origem.
  6. Selecione Druva Backup como o Tipo de registro.
  7. 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.com
    
  8. Copie esse endereço de e-mail para usar na próxima etapa.

Configurar o feed

  1. Clique em Próxima.
  2. 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

  3. Clique em Próxima.

  4. 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.

  1. Acesse Cloud Storage > Buckets.
  2. Clique no nome do bucket (por exemplo, druva-backup-logs).
  3. Acesse a guia Permissões.
  4. Clique em Conceder acesso.
  5. 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.
  6. 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.