Mengumpulkan log PingIDM (sebelumnya ForgeRock OpenIDM)

Versi Parser: 4.0

Didukung di:

Dokumen ini menjelaskan cara menyerap log PingIDM (sebelumnya dikenal sebagai ForgeRock OpenIDM) ke Google Security Operations menggunakan Google Cloud Storage V2.

PingIDM adalah platform pengelolaan identitas yang menyediakan penyediaan pengguna, sinkronisasi, pengelolaan sandi, dan tata kelola akses. Layanan ini mencatat peristiwa siklus proses identitas, upaya autentikasi, operasi rekonsiliasi, dan perubahan konfigurasi ke log audit yang dapat diakses melalui REST.

Sebelum memulai

Pastikan Anda memiliki prasyarat berikut:

  • Instance Google SecOps.
  • Project GCP dengan Cloud Storage API yang diaktifkan.
  • Izin untuk membuat dan mengelola bucket GCS dan kebijakan IAM.
  • Izin untuk membuat layanan Cloud Run, topik Pub/Sub, dan tugas Cloud Scheduler.
  • Akses istimewa ke instance ForgeRock OpenIDM atau PingIDM dengan kredensial administratif.

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, forgerock-openidm-audit-logs)
    Location type Pilih sesuai kebutuhan Anda (Region, Dual-region, Multi-region)
    Location Pilih lokasi (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 ForgeRock OpenIDM

Mendapatkan URL dasar ForgeRock OpenIDM

  1. Login ke instance ForgeRock OpenIDM atau PingIDM Anda.
  2. Catat URL dasar Anda dari kolom URL browser.
    • Format: https://openidm.example.com
    • Jangan sertakan garis miring di akhir atau jalur seperti /admin.

Mendapatkan kredensial administratif

  1. Dapatkan kredensial administratif untuk instance ForgeRock OpenIDM Anda.
  2. Anda memerlukan:
    • Username: Nama pengguna administratif (misalnya, openidm-admin)
    • Password: Sandi administratif

Memverifikasi izin

  1. Login ke ForgeRock OpenIDM.
  2. Buka Configure > System Preferences > Audit.
  3. Jika Anda dapat melihat konfigurasi dan topik audit, berarti Anda memiliki izin yang diperlukan.
  4. Jika Anda tidak dapat melihat opsi ini, hubungi administrator Anda untuk memberikan izin baca audit.

Menguji akses API

  • Uji kredensial Anda sebelum melanjutkan integrasi:

    # Replace with your actual credentials
    OPENIDM_BASE_URL="[https://openidm.example.com](https://openidm.example.com)"
    OPENIDM_USERNAME="openidm-admin"
    OPENIDM_PASSWORD="your-admin-password"
    
    # Test API access to authentication audit topic
    curl -v \
        -H "X-OpenIDM-Username: ${OPENIDM_USERNAME}" \
        -H "X-OpenIDM-Password: ${OPENIDM_PASSWORD}" \
        -H "Accept-API-Version: resource=1.0" \
        -H "Accept: application/json" \
        "${OPENIDM_BASE_URL}/openidm/audit/authentication?_queryFilter=true&_pageSize=1"
    

Respons yang diharapkan: HTTP 200 dengan JSON yang berisi peristiwa audit.

Membuat akun layanan untuk fungsi Cloud Run

Fungsi Cloud Run memerlukan akun layanan dengan izin untuk menulis ke bucket GCS dan dipanggil oleh Pub/Sub.

Membuat akun layanan

  1. Di Konsol GCP, buka IAM & Admin > Service Accounts.
  2. Klik Create Service Account.
  3. Berikan detail konfigurasi berikut:
    • Service account name: forgerock-openidm-collector-sa
    • Service account description: Service account for Cloud Run function to collect ForgeRock OpenIDM logs
  4. Klik Create and Continue.
  5. Di bagian Grant this service account access to project, tambahkan peran berikut:
    1. Storage Object Admin: Untuk menulis log ke bucket GCS dan mengelola state file.
    2. Cloud Run Invoker: Untuk mengizinkan Pub/Sub memanggil fungsi.
    3. Cloud Functions Invoker: Untuk mengizinkan pemanggilan fungsi.
  6. Klik Continue, lalu Done.

Memberikan izin IAM di bucket GCS

  1. Buka Cloud Storage > Buckets.
  2. Klik nama bucket Anda (misalnya, forgerock-openidm-audit-logs).
  3. Buka tab Izin.
  4. Klik Grant access.
  5. Berikan detail konfigurasi berikut:
    • Add principals: Masukkan email akun layanan (misalnya, forgerock-openidm-collector-sa@PROJECT_ID.iam.gserviceaccount.com).
    • Assign roles: Pilih Storage Object Admin.
  6. Klik Simpan.

Membuat topik Pub/Sub

  1. Di Konsol GCP, buka Pub/Sub > Topics.
  2. Klik Create topic.
  3. Berikan detail konfigurasi berikut:
    • ID Topik: forgerock-openidm-trigger
    • Biarkan setelan lainnya sesuai default.
  4. Klik Create.

Membuat fungsi Cloud Run untuk mengumpulkan log

  1. Di Konsol GCP, buka Cloud Run.
  2. Klik Create service.
  3. Pilih Function (gunakan editor inline untuk membuat fungsi).
  4. Di bagian Configure, berikan detail konfigurasi berikut:

    Setelan Nilai
    Nama layanan forgerock-openidm-collector
    Region Pilih region yang cocok dengan bucket GCS Anda (misalnya, us-central1)
    Runtime Pilih Python 3.12 atau yang lebih baru
  5. Di bagian Trigger:

    1. Klik + Tambahkan pemicu.
    2. Pilih Cloud Pub/Sub.
    3. Di Select a Cloud Pub/Sub topic, pilih forgerock-openidm-trigger.
    4. Klik Simpan.
  6. Di bagian Authentication:

    1. Pilih Wajibkan autentikasi.
    2. Periksa Identity and Access Management (IAM).
  7. Scroll ke bawah dan luaskan Containers, Networking, Security.

  8. Buka tab Keamanan:

    • Service account: Pilih forgerock-openidm-collector-sa.
  9. Buka tab Penampung:

    1. Klik Variables & Secrets.
    2. Klik + Add variable untuk setiap variabel lingkungan:
    Nama Variabel Nilai Contoh Deskripsi
    GCS_BUCKET forgerock-openidm-audit-logs Nama bucket GCS
    GCS_PREFIX openidm Awalan untuk file log
    STATE_KEY openidm/state.json Jalur file status
    OPENIDM_BASE_URL https://openidm.example.com URL dasar OpenIDM
    OPENIDM_USERNAME openidm-admin Nama pengguna admin OpenIDM
    OPENIDM_PASSWORD your-admin-password Sandi admin OpenIDM
    AUDIT_TOPICS access,activity,authentication,config,sync Topik yang dipisahkan koma
    PAGE_SIZE 100 Data per halaman
    MAX_PAGES 50 Halaman maks per topik
  10. Di bagian Permintaan:

    • Waktu tunggu permintaan: 600 detik.
  11. Buka tab Setelan:

    • Resources: Memori 512 MiB, 1 CPU.
  12. Klik Create. Setelah layanan dibuat, editor kode inline akan terbuka.

Menambahkan kode fungsi

  1. Masukkan main di kolom Entry point.
  2. Buat dua file di editor:

    • main.py:
    import functions_framework
    from google.cloud import storage
    import json
    import os
    import urllib3
    from datetime import datetime, timezone
    
    # Initialize HTTP client with timeouts
    http = urllib3.PoolManager(
        timeout=urllib3.Timeout(connect=5.0, read=30.0),
        retries=False,
    )
    
    # Initialize Storage client
    storage_client = storage.Client()
    
    # Environment variables
    GCS_BUCKET = os.environ.get('GCS_BUCKET')
    GCS_PREFIX = os.environ.get('GCS_PREFIX', 'openidm')
    STATE_KEY = os.environ.get('STATE_KEY', 'openidm/state.json')
    OPENIDM_BASE_URL = os.environ.get('OPENIDM_BASE_URL')
    OPENIDM_USERNAME = os.environ.get('OPENIDM_USERNAME')
    OPENIDM_PASSWORD = os.environ.get('OPENIDM_PASSWORD')
    AUDIT_TOPICS = os.environ.get('AUDIT_TOPICS', 'access,activity,authentication,config,sync').split(',')
    PAGE_SIZE = int(os.environ.get('PAGE_SIZE', '100'))
    MAX_PAGES = int(os.environ.get('MAX_PAGES', '50'))
    
    @functions_framework.cloud_event
    def main(cloud_event):
        """
        Cloud Run function triggered by Pub/Sub to fetch ForgeRock OpenIDM logs and write to GCS.
        """
        if not all([GCS_BUCKET, OPENIDM_BASE_URL, OPENIDM_USERNAME, OPENIDM_PASSWORD]):
            print('Error: Missing required environment variables')
            return
    
        try:
            bucket = storage_client.bucket(GCS_BUCKET)
            state = load_state(bucket, STATE_KEY)
    
            all_events = []
            for topic in AUDIT_TOPICS:
                topic = topic.strip()
                print(f"Fetching audit logs for topic: {topic}")
                events = fetch_audit_logs(topic, state.get(topic, {}))
                all_events.extend(events)
    
                if events:
                    latest_timestamp = max(e.get('timestamp', '') for e in events)
                    state[topic] = {
                        'last_timestamp': latest_timestamp,
                        'last_run': datetime.now(timezone.utc).isoformat(),
                        'events_count': len(events)
                    }
    
            if all_events:
                write_to_gcs(bucket, all_events)
                save_state(bucket, STATE_KEY, state)
                print(f"Successfully processed {len(all_events)} audit events")
            else:
                print("No new audit events to process")
    
        except Exception as e:
            print(f'Error processing logs: {str(e)}')
            raise
    
    def load_state(bucket, key):
        try:
            blob = bucket.blob(key)
            if blob.exists():
                return json.loads(blob.download_as_text())
        except Exception as e:
            print(f"Warning: Could not load state: {e}")
        return {}
    
    def save_state(bucket, key, state):
        try:
            blob = bucket.blob(key)
            blob.upload_from_string(json.dumps(state, indent=2), content_type='application/json')
        except Exception as e:
            print(f"Warning: Could not save state: {e}")
    
    def fetch_audit_logs(topic, topic_state):
        base_url = OPENIDM_BASE_URL.rstrip('/')
        all_events = []
        last_timestamp = topic_state.get('last_timestamp')
        query_filter = 'true' if not last_timestamp else f'timestamp gt "{last_timestamp}"'
        page_offset = 0
        page_count = 0
    
        while page_count < MAX_PAGES:
            try:
                url = f"{base_url}/openidm/audit/{topic}"
                params = {
                    '_queryFilter': query_filter,
                    '_pageSize': str(PAGE_SIZE),
                    '_pagedResultsOffset': str(page_offset),
                    '_sortKeys': 'timestamp'
                }
    
                headers = {
                    'X-OpenIDM-Username': OPENIDM_USERNAME,
                    'X-OpenIDM-Password': OPENIDM_PASSWORD,
                    'Accept-API-Version': 'resource=1.0',
                    'Accept': 'application/json'
                }
    
                response = http.request('GET', url, fields=params, headers=headers)
                if response.status != 200:
                    print(f"API error for topic {topic}: {response.status}")
                    break
    
                data = json.loads(response.data.decode('utf-8'))
                events = data.get('result', [])
                if not events:
                    break
    
                all_events.extend(events)
                page_offset += PAGE_SIZE
                page_count += 1
                if len(events) < PAGE_SIZE:
                    break
            except Exception as e:
                print(f"Error for topic {topic}: {str(e)}")
                break
        return all_events
    
    def write_to_gcs(bucket, events):
        timestamp = datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')
        filename = f"{GCS_PREFIX}/openidm_audit_{timestamp}.json"
        ndjson_content = '\n'.join([json.dumps(event) for event in events])
        bucket.blob(filename).upload_from_string(ndjson_content, content_type='application/x-ndjson')
    
    • requirements.txt:
    functions-framework==3.*
    google-cloud-storage==2.*
    urllib3>=2.0.0
    
  3. Klik Deploy. Deployment memerlukan waktu 2–3 menit.

Buat tugas Cloud Scheduler

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

    Setelan Nilai
    Nama forgerock-openidm-collector-hourly
    Region Pilih region yang sama dengan fungsi Cloud Run
    Frekuensi 0 * * * * (setiap jam)
    Zona Waktu Pilih zona waktu (UTC direkomendasikan)
    Jenis target Pub/Sub
    Topik forgerock-openidm-trigger
    Isi pesan {}
  4. Klik Create.

Opsi frekuensi jadwal

Frekuensi Ekspresi Cron Kasus Penggunaan
Setiap 5 menit */5 * * * * Volume tinggi, latensi rendah
Setiap jam 0 * * * * Standar (direkomendasikan)
Harian 0 0 * * * Pengumpulan batch

Menguji integrasi

  1. Di Cloud Scheduler, klik Force run pada tugas Anda.
  2. Verifikasi operasi di log Cloud Run. Cari: Successfully processed X audit events.
  3. Pastikan file json baru ada di bucket Cloud Storage Anda di folder openidm/.

Mengambil akun layanan Google SecOps

Mengonfigurasi feed di Google SecOps

  1. Buka Setelan > Pengelolaan Data > Feed. Jika Anda menggunakan platform khusus SIEM, buka Settings > Feeds.
  2. Klik Tambahkan Feed Baru > Konfigurasi satu feed.
  3. Nama feed: ForgeRock OpenIDM Audit Logs.
  4. Source type: Google Cloud Storage V2.
  5. Jenis log: FORGEROCK_OPENIDM.
  6. Klik Get Service Account dan salin email yang diberikan (misalnya, chronicle-12345...).
  7. Klik Berikutnya.
  8. URL bucket penyimpanan: gs://forgerock-openidm-audit-logs/openidm/.
  9. Opsi penghapusan sumber: Pilih sesuai preferensi (misalnya, Jangan pernah).
  10. Klik Berikutnya, tinjau, lalu klik Kirim.

Memberikan izin IAM

  1. Buka Cloud Storage > Buckets.
  2. Pilih bucket Anda, lalu klik tab Permissions.
  3. Klik Grant access.
  4. Add principals: Tempel email akun layanan Google SecOps.
  5. Assign roles: Pilih Storage Object Viewer.
  6. Klik Simpan.

Tabel pemetaan UDM

Kolom Log Pemetaan UDM Logika
fluenttag_label, topic_label, context_roles_label additional.fields Key-value pair untuk konteks.
Via intermediary.hostname Nama host proxy/perantara.
x_forwarded_ip, caller.callerIps intermediary.ip IP perantara.
timestamp metadata.event_timestamp Stempel waktu peristiwa.
transactionId metadata.product_deployment_id ID transaksi unik.
eventName metadata.product_event_type Nama peristiwa dari ForgeRock.
_id metadata.product_log_id ID log unik.
request_method network.http.method Metode HTTP yang digunakan.
response.statusCode network.http.response_code Kode status HTTP.
user_agent network.http.user_agent String agen pengguna lengkap.
client.ip, context.ipAddress principal.ip IP sumber pelaku.
userId, principalData.0 principal.user.userid ID pengguna yang bertindak.
security_action security_result.action Keputusan keamanan diambil.
level security_result.severity Tingkat keparahan yang dipetakan.
server.ip target.ip IP sistem target.
http.request.path target.url URL/Jalur Target.
T/A metadata.product_name Setel ke ForgeRock OpenIDM.
T/A metadata.vendor_name Tetapkan ke ForgeRock.
elapsed_time" and "X-Content-Type-Options additional.fields Dipetakan dari log perubahan
trackingIds.0 metadata.product_log_id Dipetakan dari log perubahan
context.userRolesProperty", "context.authenticationId", and "context.authenticationIdProperty principal.user.attribute.roles Dipetakan dari log perubahan
context.component", "context.moduleId", and "context.queryId principal.resource.attribute.labels Dipetakan dari log perubahan
context.roles", "_normalized.fieldNames", and "_eventId additional.fields Dipetakan dari log perubahan

Log Perubahan

Melihat Log Perubahan untuk parser ini

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