Mengumpulkan log Druva Backup

Didukung di:

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

Druva adalah platform perlindungan dan pengelolaan data berbasis cloud yang menyediakan layanan pencadangan, pemulihan dari bencana, dan pengarsipan untuk endpoint, aplikasi SaaS, dan workload perusahaan. Platform ini menghasilkan jejak audit yang komprehensif, peristiwa pencadangan, aktivitas pemulihan, dan pemberitahuan keamanan 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 Platform Cloud Druva
  • Akses ke Pusat Integrasi Druva 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
    Beri nama bucket Anda Masukkan nama yang unik secara global (misalnya, druva-backup-logs)
    Location type Pilih berdasarkan kebutuhan Anda (Region, Dual-region, Multi-region)
    Location Pilih lokasi yang paling dekat dengan instance Google SecOps Anda (misalnya, us-central1)
    Kelas penyimpanan Standar (direkomendasikan untuk log yang sering diakses)
    Access control Seragam (direkomendasikan)
    Alat perlindungan Opsional: Aktifkan pembuatan versi objek atau kebijakan retensi
  6. Klik Create.

Kumpulkan kredensial Druva API

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

Membuat kredensial API

  1. Login ke Druva Cloud Platform Console.
  2. Dari menu Global Navigation, pilih Integration Center.
  3. Di panel kiri, klik Kredensial API.
  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 Administrator Cloud Druva untuk mengizinkan akses penuh ke pengambilan dan modifikasi data.
    2. Atau, pilih Administrator Produk dan pilih: Peran Administrator Cloud (Hanya Baca): Untuk membatasi akses hanya pada pengambilan data 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:
    • Nama akun layanan: Masukkan druva-backup-function (atau nama deskriptif)
    • Deskripsi akun layanan: Masukkan Service account for Druva Backup Cloud Run function
  4. Klik Create and Continue.
  5. Di bagian Berikan akun layanan ini akses ke project, tambahkan peran berikut:
    1. Klik Pilih peran, 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 Tambahkan langganan default.
  5. Klik Create.

Membuat fungsi Cloud Run

Menyiapkan kode fungsi

Buat 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 terdekat dengan bucket GCS Anda (misalnya, us-central1)
    • Trigger type: Pilih Cloud Pub/Sub
    • Topik Cloud Pub/Sub: Pilih druva-backup-trigger
    • Akun layanan: 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 Cloud Run Function, buka bagian Runtime, build, connections and security settings.
  2. Di bagian Runtime environment variables, 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 proses 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.
    • Frekuensi: Masukkan */30 * * * * (setiap 30 menit)
    • Zona waktu: Pilih zona waktu pilihan Anda (misalnya, UTC)
  4. Klik Lanjutkan.

  5. Konfigurasi Target:

    • Jenis target: Pilih Pub/Sub
    • Topik Cloud Pub/Sub: 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 memicu fungsi secara langsung.
  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

Dapatkan email akun layanan

  1. Buka Setelan SIEM > Feed.
  2. Klik Tambahkan Feed 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 Jenis log.
  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:

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

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

      • Jangan pernah: Tidak pernah menghapus file apa pun setelah transfer (direkomendasikan untuk pengujian)
      • Hapus file yang ditransfer: Menghapus file setelah transfer berhasil
      • Hapus file yang ditransfer dan direktori kosong: Menghapus file dan direktori kosong setelah transfer berhasil
    • Usia File Maksimum: Menyertakan file yang diubah dalam beberapa 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 baru Anda di layar Selesaikan, lalu klik Kirim.

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)
    • Tetapkan peran: 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 Disetel ke "AUTHTYPE_UNSPECIFIED" jika pemrakarsa cocok dengan regex 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; atau "GENERIC_EVENT"
eventID metadata.product_log_id Dikonversi ke string
metadata.product_name Tetapkan ke "DRUVA_BACKUP"
clientVersion metadata.product_version Nilai disalin secara langsung
inSyncDataSourceName principal.asset.hostname Nilai disalin secara langsung
ip principal.asset.ip Digabungkan dari IP
inSyncDataSourceName principal.hostname Nilai disalin secara langsung
ip principal.ip Digabungkan dari IP
clientOS principal.platform Disetel 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 secara langsung
profileID principal.resource.product_object_id Dikonversi ke string
eventState security_result.action Ditetapkan ke "ALLOW" jika cocok dengan (?i)Success, atau "BLOCK"
eventState security_result.action_details Nilai disalin secara langsung
tingkat keseriusan, security_result.severity Setel ke "RENDAH" jika dalam [0,1,2,3,RENDAH]; "SEDANG" jika dalam [4,5,6,SEDANG,SUBSTANSIAL,INFO]; "TINGGI" jika dalam [7,8,TINGGI,PARAH]; "KRITIS" jika dalam [9,10,SANGAT-TINGGI,KRITIS]
inSyncUserEmail, inisiator target.user.email_addresses Digabungkan dari inSyncUserEmail; juga dari pemrakarsa jika cocok dengan regex email
inSyncUserName target.user.userid Nilai disalin secara langsung
metadata.vendor_name Tetapkan ke "DRUVA_BACKUP"

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