Mengumpulkan log Druva Backup

Versi Parser: 2.0

Didukung di:

Dokumen ini menjelaskan cara mengumpulkan log Druva Backup dengan menyiapkan fungsi Google Cloud Run yang mengambil peristiwa dari Druva REST API dan menulisnya ke bucket Google Cloud Storage, lalu mengonfigurasi feed Google Security Operations menggunakan Google Cloud Storage V2.

Druva adalah platform pengelolaan dan perlindungan data berbasis cloud yang menyediakan layanan pencadangan, disaster recovery, dan pengarsipan untuk endpoint, aplikasi SaaS, dan workload perusahaan. Platform ini menghasilkan jejak audit, peristiwa pencadangan, aktivitas pemulihan, dan notifikasi keamanan yang komprehensif yang dapat diintegrasikan dengan solusi SIEM untuk pemantauan dan kepatuhan.

Sebelum memulai

Pastikan Anda memiliki prasyarat berikut:

  • Instance Google SecOps
  • Project Google Cloud yang mengaktifkan penagihan
  • Google Cloud API berikut diaktifkan:
    • Cloud Run Functions API
    • Cloud Scheduler API
    • Cloud Storage API
    • Pub/Sub API
    • IAM API
  • Akses Administrator Cloud Druva ke Konsol Druva Cloud Platform
  • Akses ke Druva Integration Center untuk pembuatan kredensial API

Membuat bucket Google Cloud Storage

  1. Buka Konsol Google Cloud.
  2. Pilih project Anda atau buat project baru.
  3. Di menu navigasi, buka Cloud Storage > Buckets.
  4. Klik Create bucket.
  5. Berikan detail konfigurasi berikut:

    Setelan Nilai
    Memberi nama bucket Anda Masukkan nama yang unik secara global (misalnya, druva-backup-logs)
    Location type Pilih sesuai kebutuhan Anda (Region, Dual-region, Multi-region)
    Location Pilih lokasi yang paling dekat dengan instance Google SecOps Anda (misalnya, us-central1)
    Storage class Standard (direkomendasikan untuk log yang sering diakses)
    Kontrol akses Seragam (direkomendasikan)
    Alat perlindungan Opsional: Mengaktifkan pembuatan versi objek atau kebijakan retensi
  6. Klik Create.

Mengumpulkan kredensial Druva API

Agar fungsi Cloud Run dapat mengambil peristiwa dari Druva, Anda perlu membuat kredensial API dengan autentikasi OAuth 2.0.

Membuat kredensial API

  1. Login ke Konsol Druva Cloud Platform.
  2. Dari menu Global Navigation, pilih Integration Center.
  3. Di panel kiri, klik API Credentials.
  4. Klik New Credentials.
  5. Di jendela New Credentials, berikan detail berikut: Name: Masukkan nama deskriptif (misalnya, Google SecOps Cloud Storage Integration).
  6. Untuk menerapkan batasan otorisasi:
    1. Pilih Druva Cloud Administrator untuk mengizinkan akses penuh ke pengambilan dan modifikasi data.
    2. Atau, pilih Product Administrator dan pilih: Peran Cloud Admin (Read Only): Untuk membatasi akses ke pengambilan data saja tanpa hak modifikasi (direkomendasikan untuk integrasi SIEM)
  7. Klik Simpan.

Mencatat kredensial API

Setelah membuat kredensial API, jendela Credential Details akan muncul:

  1. Klik ikon salin di samping Client ID untuk menyalin nilai ke papan klip Anda.
  2. Simpan Client ID dengan aman (misalnya, McNkxxxx4Vicxxxx4Ldpxxxx/09Uxxxx).
  3. Klik ikon salin di samping Secret Key untuk menyalin nilai ke papan klip Anda.
  4. Simpan Kunci Rahasia dengan aman (misalnya, Xmcxxxx8j5xxxx6NxxxxRbRxxxxNNyPt).

Membuat akun layanan

Buat akun layanan khusus untuk fungsi Cloud Run guna mengakses Google Cloud Storage.

  1. Di Konsol Google Cloud, buka IAM & Admin > Service Accounts.
  2. Klik Create Service Account.
  3. Berikan detail konfigurasi berikut:
    • Service account name: Masukkan druva-backup-function (atau nama deskriptif)
    • Service account description: Masukkan Service account for Druva Backup Cloud Run function
  4. Klik Create and Continue.
  5. Di bagian Grant this service account access to project, tambahkan peran berikut:
    1. Klik Select a role, lalu pilih Storage Object Admin.
    2. Klik Add another role, lalu pilih Cloud Run Invoker.
  6. Klik Lanjutkan.
  7. Klik Done.
  8. Catat email akun layanan (misalnya, druva-backup-function@PROJECT_ID.iam.gserviceaccount.com).

Membuat topik Pub/Sub

Buat topik Pub/Sub yang akan digunakan Cloud Scheduler untuk memicu fungsi Cloud Run.

  1. Di Konsol Google Cloud, buka Pub/Sub > Topics.
  2. Klik Buat Topik.
  3. Berikan detail konfigurasi berikut:
    • ID Topik: Masukkan druva-backup-trigger
  4. Hapus centang pada Add a default subscription.
  5. Klik Create.

Membuat fungsi Cloud Run

Menyiapkan kode fungsi

Membuat fungsi Cloud Run yang melakukan autentikasi dengan Druva API menggunakan kredensial klien OAuth 2.0, mengambil peristiwa melalui endpoint peristiwa dengan penomoran halaman, dan menulis hasilnya sebagai NDJSON ke bucket GCS.

Men-deploy fungsi Cloud Run

  1. Di Konsol Google Cloud, buka Cloud Run Functions.
  2. Klik Create Function.
  3. Berikan detail konfigurasi berikut:

    • Environment: Pilih 2nd gen
    • Nama fungsi: Masukkan druva-backup-to-gcs
    • Region: Pilih region yang paling dekat dengan bucket GCS Anda (misalnya, us-central1)
    • Trigger type: Pilih Cloud Pub/Sub
    • Cloud Pub/Sub topic: Pilih druva-backup-trigger
    • Service account: Pilih druva-backup-function@PROJECT_ID.iam.gserviceaccount.com
    • Memori yang dialokasikan: 512 MiB
    • Waktu tunggu: 540 detik
    • Jumlah maksimum instance: 1
  4. Klik Berikutnya.

  5. Pilih Python 3.11 sebagai Runtime.

  6. Tetapkan Entry point ke main.

  7. Di editor Source code, ganti konten main.py dengan kode berikut:

    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. Ganti konten requirements.txt dengan konten berikut:

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

Mengonfigurasi variabel lingkungan

  1. Di konfigurasi fungsi Cloud Run, buka bagian Runtime, build, connections and security settings.
  2. Di bagian Variabel lingkungan runtime, tambahkan variabel berikut:

    • GCS_BUCKET: Nama bucket GCS Anda (misalnya, druva-backup-logs)
    • GCS_PREFIX: Jalur awalan untuk file log (misalnya, druva_backup)
    • STATE_KEY: Nama file status (misalnya, druva_state.json)
    • DRUVA_BASE_URL: URL dasar Druva API:
      • apis.druva.com untuk Druva Cloud (Standard)
      • govcloudapis.druva.com untuk Druva GovCloud
    • CLIENT_ID: Client ID dari kredensial Druva API
    • CLIENT_SECRET: Kunci Rahasia dari kredensial Druva API
    • MAX_RECORDS: Jumlah maksimum data yang akan diambil per pemanggilan (misalnya, 10000)
    • PAGE_SIZE: Jumlah peristiwa per halaman API (maksimum 500)
    • LOOKBACK_HOURS: Jumlah jam untuk melihat kembali operasi pertama (misalnya, 24)
  3. Klik Deploy.

  4. Tunggu hingga deployment berhasil diselesaikan.

Buat tugas Cloud Scheduler

Buat tugas Cloud Scheduler untuk memicu fungsi Cloud Run secara berkala.

  1. Di Konsol Google Cloud, buka Cloud Scheduler.
  2. Klik Create Job.
  3. Berikan detail konfigurasi berikut:

    • Nama: Masukkan druva-backup-scheduler
    • Region: Pilih region yang sama dengan fungsi Cloud Run Anda (misalnya, us-central1)
    • Deskripsi: Masukkan Triggers Druva Backup log collection every 30 minutes
    • Frequency: Masukkan */30 * * * * (setiap 30 menit)
    • Zona waktu: Pilih zona waktu yang Anda inginkan (misalnya, UTC)
  4. Klik Lanjutkan.

  5. Konfigurasikan Target:

    • Target type: Pilih Pub/Sub
    • Cloud Pub/Sub topic: Pilih druva-backup-trigger
    • Isi pesan: Masukkan {"trigger": "scheduled"}
  6. Klik Create.

Menguji tugas Cloud Scheduler

  1. Dalam daftar Cloud Scheduler, temukan druva-backup-scheduler.
  2. Klik Force Run untuk langsung memicu fungsi.
  3. Verifikasi eksekusi dengan memeriksa:
    • Log fungsi Cloud Run di Cloud Run functions > druva-backup-to-gcs > Logs
    • Bucket GCS untuk file NDJSON baru di Cloud Storage > druva-backup-logs

Mengambil akun layanan Google SecOps dan mengonfigurasi feed

Mendapatkan email akun layanan

  1. Buka Setelan > Pengelolaan Data > Feed. Jika Anda menggunakan platform khusus SIEM, buka Settings > Feeds.
  2. Klik Tambahkan Feed Berita Baru.
  3. Klik Konfigurasi satu feed.
  4. Di kolom Nama feed, masukkan nama untuk feed (misalnya, Druva Backup Events).
  5. Pilih Google Cloud Storage V2 sebagai Source type.
  6. Pilih Druva Backup sebagai Log type.
  7. Klik Get Service Account. Email akun layanan yang unik akan ditampilkan, misalnya:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  8. Salin alamat email ini untuk digunakan di langkah berikutnya.

Mengonfigurasi feed

  1. Klik Berikutnya.
  2. Tentukan nilai untuk parameter input berikut:

    • Storage bucket URL: Masukkan URI bucket GCS dengan jalur awalan:

      gs://druva-backup-logs/druva_backup/
      
    • Opsi penghapusan sumber: Pilih opsi penghapusan sesuai preferensi Anda:

      • Never: Tidak pernah menghapus file apa pun setelah transfer (direkomendasikan untuk pengujian)
      • Delete transferred files: Menghapus file setelah transfer berhasil
      • Hapus file yang ditransfer dan direktori kosong: Menghapus file dan direktori kosong setelah transfer berhasil
    • Usia File Maksimum: Sertakan file yang diubah dalam jumlah hari terakhir (defaultnya adalah 180 hari)

    • Namespace aset: Namespace aset

    • Label penyerapan: Label yang akan diterapkan ke peristiwa dari feed ini

  3. Klik Berikutnya.

  4. Tinjau konfigurasi feed berita baru Anda di layar Finalize, lalu klik Submit.

Memberikan izin IAM ke akun layanan Google SecOps

Akun layanan Google SecOps memerlukan peran Storage Object Viewer di bucket GCS Anda untuk membaca file log yang ditulis oleh fungsi Cloud Run.

  1. Buka Cloud Storage > Buckets.
  2. Klik nama bucket Anda (misalnya, druva-backup-logs).
  3. Buka tab Izin.
  4. Klik Grant access.
  5. Berikan detail konfigurasi berikut:
    • Add principals: Tempel email akun layanan Google SecOps (misalnya, chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com)
    • Assign roles: Pilih Storage Object Viewer
  6. Klik Simpan.

Tabel pemetaan UDM

Kolom Log Pemetaan UDM Logika
inSyncUserID, eventsGroupId, FilesMissed, FilesBackedup, TotalBackupSize, TotalBytesTransferred, facility, inSyncDataSourceID, initiator, event_type additional.fields Digabungkan dengan label yang dibuat dari setiap kolom jika tidak kosong
inisiator extensions.auth.type Setel ke "AUTHTYPE_UNSPECIFIED" jika inisiator cocok dengan ekspresi reguler email
metadata.event_type Ditetapkan ke "USER_LOGIN" jika has_target_user benar dan has_principal benar; "STATUS_UPDATE" jika has_principal benar dan has_target salah; jika tidak, "GENERIC_EVENT"
eventID metadata.product_log_id Dikonversi ke string
metadata.product_name Tetapkan ke "DRUVA_BACKUP"
clientVersion metadata.product_version Nilai disalin langsung
inSyncDataSourceName principal.asset.hostname Nilai disalin langsung
ip principal.asset.ip Digabungkan dari IP
inSyncDataSourceName principal.hostname Nilai disalin langsung
ip principal.ip Digabungkan dari IP
clientOS principal.platform Setel ke "LINUX" jika cocok dengan (?i)Linux; "WINDOWS" jika cocok dengan (?i)windows; "MAC" jika cocok dengan (?i)mac
profileName principal.resource.name Nilai disalin langsung
profileID principal.resource.product_object_id Dikonversi ke string
eventState security_result.action Setel ke "ALLOW" jika cocok dengan (?i)Success, jika tidak, setel ke "BLOCK"
eventState security_result.action_details Nilai disalin langsung
tingkat keseriusan, security_result.severity Setel ke "LOW" jika dalam [0,1,2,3,LOW]; "MEDIUM" jika dalam [4,5,6,MEDIUM,SUBSTANTIAL,INFO]; "HIGH" jika dalam [7,8,HIGH,SEVERE]; "CRITICAL" jika dalam [9,10,VERY-HIGH,CRITICAL]
inSyncUserEmail, initiator target.user.email_addresses Digabungkan dari inSyncUserEmail; juga dari inisiator jika cocok dengan ekspresi reguler email
inSyncUserName target.user.userid Nilai disalin langsung
metadata.vendor_name Tetapkan ke "DRUVA_BACKUP"

Log Perubahan

Melihat Log Perubahan untuk parser ini

Perlu bantuan lain? Dapatkan jawaban dari anggota Komunitas dan profesional Google SecOps.