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

Buat 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, forgerock-openidm-audit-logs)
    Location type Pilih berdasarkan kebutuhan Anda (Region, Dual-region, Multi-region)
    Location Pilih lokasi (misalnya, us-central1)
    Kelas penyimpanan Standar (direkomendasikan untuk log yang sering diakses)
    Kontrol akses Seragam (direkomendasikan)
    Alat perlindungan Opsional: Aktifkan 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 atau jalur di akhir seperti /admin.

Mendapatkan kredensial administratif

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

Memverifikasi izin

  1. Login ke ForgeRock OpenIDM.
  2. Buka Konfigurasi > Preferensi Sistem > Audit.
  3. Jika Anda dapat melihat konfigurasi audit dan topik, 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.

Buat 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:
    • Nama akun layanan: forgerock-openidm-collector-sa
    • Deskripsi akun layanan: 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 file status.
    2. Cloud Run Invoker: Untuk mengizinkan Pub/Sub memanggil fungsi.
    3. Cloud Functions Invoker: Untuk mengizinkan pemanggilan fungsi.
  6. Klik Lanjutkan, lalu klik Selesai.

Memberikan izin IAM pada 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:
    • Tambahkan prinsipal: Masukkan email akun layanan (misalnya, forgerock-openidm-collector-sa@PROJECT_ID.iam.gserviceaccount.com).
    • Tetapkan peran: Pilih Storage Object Admin.
  6. Klik Simpan.

Membuat topik Pub/Sub

  1. Di GCP Console, 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 Konfigurasi, 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 Pemicu:

    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 Security:

    • Akun layanan: Pilih forgerock-openidm-collector-sa.
  9. Buka tab Containers:

    1. Klik Variables & Secrets.
    2. Klik + Tambahkan variabel 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 maksimum per topik
  10. Di bagian Permintaan:

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

    • Resource: Memori 512 MiB, CPU 1.
  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 eksekusi 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 SIEM Settings > Feeds.
  2. Klik Tambahkan Feed Baru > Konfigurasi satu feed.
  3. Nama feed: ForgeRock OpenIDM Audit Logs.
  4. Jenis sumber: 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. Tetapkan peran: Pilih Storage Object Viewer.
  6. Klik Simpan.

Tabel pemetaan UDM

Kolom Log Pemetaan UDM Logika
fluenttag_label, topic_label, context_roles_label additional.fields Pasangan nilai kunci 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 telah 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 Disetel 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.