Mengumpulkan log Druva Backup
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
- Buka Konsol Google Cloud.
- Pilih project Anda atau buat project baru.
- Di menu navigasi, buka Cloud Storage > Buckets.
- Klik Create bucket.
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 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
- Login ke Druva Cloud Platform Console.
- Dari menu Global Navigation, pilih Integration Center.
- Di panel kiri, klik Kredensial API.
- Klik New Credentials.
- Di jendela New Credentials, berikan detail berikut:
Name: Masukkan nama deskriptif (misalnya,
Google SecOps Cloud Storage Integration). - Untuk menerapkan batasan otorisasi:
- Pilih Administrator Cloud Druva untuk mengizinkan akses penuh ke pengambilan dan modifikasi data.
- 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)
- Klik Simpan.
Mencatat kredensial API
Setelah membuat kredensial API, jendela Credential Details akan muncul:
- Klik ikon salin di samping Client ID untuk menyalin nilai ke papan klip Anda.
- Simpan Client ID dengan aman (misalnya,
McNkxxxx4Vicxxxx4Ldpxxxx/09Uxxxx). - Klik ikon salin di samping Secret Key untuk menyalin nilai ke papan klip Anda.
Simpan Kunci Rahasia dengan aman (misalnya,
Xmcxxxx8j5xxxx6NxxxxRbRxxxxNNyPt).
Membuat akun layanan
Buat akun layanan khusus untuk fungsi Cloud Run guna mengakses Google Cloud Storage.
- Di Konsol Google Cloud, buka IAM & Admin > Service Accounts.
- Klik Create Service Account.
- 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
- Nama akun layanan: Masukkan
- Klik Create and Continue.
- Di bagian Berikan akun layanan ini akses ke project, tambahkan peran berikut:
- Klik Pilih peran, lalu pilih Storage Object Admin.
- Klik Add another role, lalu pilih Cloud Run Invoker.
- Klik Lanjutkan.
- Klik Done.
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.
- Di konsol Google Cloud, buka Pub/Sub > Topics.
- Klik Buat Topik.
- Berikan detail konfigurasi berikut:
- ID Topik: Masukkan
druva-backup-trigger
- ID Topik: Masukkan
- Hapus centang Tambahkan langganan default.
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
- Di konsol Google Cloud, buka Cloud Run functions.
- Klik Create Function.
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:
540detik - Jumlah maksimum instance:
1
Klik Berikutnya.
Pilih Python 3.11 sebagai Runtime.
Tetapkan Entry point ke
main.Di editor Source code, ganti konten
main.pydengan 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"Ganti konten
requirements.txtdengan konten berikut:requests>=2.31.0 google-cloud-storage>=2.14.0
Mengonfigurasi variabel lingkungan
- Di konfigurasi Cloud Run Function, buka bagian Runtime, build, connections and security settings.
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.comuntuk Druva Cloud (Standard)govcloudapis.druva.comuntuk Druva GovCloud
CLIENT_ID: Client ID dari kredensial Druva APICLIENT_SECRET: Kunci Rahasia dari kredensial Druva APIMAX_RECORDS: Jumlah maksimum data yang akan diambil per pemanggilan (misalnya,10000)PAGE_SIZE: Jumlah peristiwa per halaman API (maksimum500)LOOKBACK_HOURS: Jumlah jam untuk melihat kembali proses pertama (misalnya,24)
Klik Deploy.
Tunggu hingga deployment berhasil diselesaikan.
Buat tugas Cloud Scheduler
Buat tugas Cloud Scheduler untuk memicu fungsi Cloud Run secara berkala.
- Di konsol Google Cloud, buka Cloud Scheduler.
- Klik Create Job.
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)
- Nama: Masukkan
Klik Lanjutkan.
Konfigurasi Target:
- Jenis target: Pilih Pub/Sub
- Topik Cloud Pub/Sub: Pilih
druva-backup-trigger - Isi pesan: Masukkan
{"trigger": "scheduled"}
Klik Create.
Menguji tugas Cloud Scheduler
- Dalam daftar Cloud Scheduler, temukan
druva-backup-scheduler. - Klik Force Run untuk memicu fungsi secara langsung.
- 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
- Buka Setelan SIEM > Feed.
- Klik Tambahkan Feed Baru.
- Klik Konfigurasi satu feed.
- Di kolom Nama feed, masukkan nama untuk feed (misalnya,
Druva Backup Events). - Pilih Google Cloud Storage V2 sebagai Source type.
- Pilih Druva Backup sebagai Jenis log.
Klik Get Service Account. Email akun layanan yang unik akan ditampilkan, misalnya:
chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.comSalin alamat email ini untuk digunakan di langkah berikutnya.
Mengonfigurasi feed
- Klik Berikutnya.
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
Klik Berikutnya.
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.
- Buka Cloud Storage > Buckets.
- Klik nama bucket Anda (misalnya,
druva-backup-logs). - Buka tab Izin.
- Klik Grant access.
- 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
- Add principals: Tempel email akun layanan Google SecOps (misalnya,
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.