Raccogli i log di PingIDM (in precedenza ForgeRock OpenIDM)

Versione parser: 4.0

Supportato in:

Questo documento spiega come importare i log di PingIDM (precedentemente noto come ForgeRock OpenIDM) in Google Security Operations utilizzando Google Cloud Storage V2.

PingIDM è una piattaforma di gestione delle identità che fornisce provisioning, sincronizzazione, gestione delle password e governance dell'accesso degli utenti. Registra eventi del ciclo di vita dell'identità, tentativi di autenticazione, operazioni di riconciliazione e modifiche alla configurazione nei log di controllo accessibili tramite REST.

Prima di iniziare

Assicurati di soddisfare i seguenti prerequisiti:

  • Un'istanza Google SecOps.
  • Un progetto GCP con l'API Storage di Cloud Storage abilitata.
  • Autorizzazioni per creare e gestire bucket GCS e policy IAM.
  • Autorizzazioni per creare servizi Cloud Run, argomenti Pub/Sub e job Cloud Scheduler.
  • Accesso privilegiato a un'istanza ForgeRock OpenIDM o PingIDM con credenziali amministrative.

Crea un bucket Google Cloud Storage

  1. Vai alla console Google Cloud.
  2. Seleziona il tuo progetto o creane uno nuovo.
  3. Nel menu di navigazione, vai a Cloud Storage > Bucket.
  4. Fai clic su Crea bucket.
  5. Fornisci i seguenti dettagli di configurazione:

    Impostazione Valore
    Assegna un nome al bucket Inserisci un nome univoco globale (ad es.forgerock-openidm-audit-logs).
    Tipo di località Scegli in base alle tue esigenze (regione singola, a due regioni, multiregionale)
    Località Seleziona la posizione (ad es.us-central1).
    Classe di archiviazione Standard (consigliato per i log ad accesso frequente)
    Controllo degli accessi Uniforme (opzione consigliata)
    Strumenti di protezione (Facoltativo) Abilita il controllo delle versioni degli oggetti o la policy di conservazione
  6. Fai clic su Crea.

Raccogliere le credenziali ForgeRock OpenIDM

Ottieni l'URL di base di ForgeRock OpenIDM

  1. Accedi all'istanza di ForgeRock OpenIDM o PingIDM.
  2. Prendi nota dell'URL di base dalla barra degli indirizzi del browser.
    • Formato: https://openidm.example.com
    • Non includere barre finali o percorsi come /admin.

Ottenere le credenziali amministrative

  1. Ottieni le credenziali amministrative per l'istanza di ForgeRock OpenIDM.
  2. Avrai bisogno di:
    • Nome utente: nome utente amministrativo (ad es. openidm-admin)
    • Password: password amministrativa

Verifica le autorizzazioni

  1. Accedi a ForgeRock OpenIDM.
  2. Vai a Configura > Preferenze di sistema > Audit.
  3. Se riesci a visualizzare la configurazione e gli argomenti di controllo, disponi delle autorizzazioni necessarie.
  4. Se non riesci a visualizzare questa opzione, contatta l'amministratore per concedere le autorizzazioni di lettura degli audit.

Testare l'accesso API

  • Testa le tue credenziali prima di procedere con l'integrazione:

    # 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"
    

Risposta prevista: HTTP 200 con JSON contenente eventi di controllo.

Crea un account di servizio per la funzione Cloud Run

La funzione Cloud Run richiede un account di servizio con autorizzazioni di scrittura nel bucket GCS e di invocazione da parte di Pub/Sub.

Crea service account

  1. Nella console Google Cloud, vai a IAM e amministrazione > Service account.
  2. Fai clic su Crea account di servizio.
  3. Fornisci i seguenti dettagli di configurazione:
    • Nome del service account: forgerock-openidm-collector-sa
    • Descrizione del service account: Service account for Cloud Run function to collect ForgeRock OpenIDM logs
  4. Fai clic su Crea e continua.
  5. Nella sezione Concedi a questo account di servizio l'accesso al progetto, aggiungi i seguenti ruoli:
    1. Amministratore oggetti Storage: per scrivere i log nel bucket GCS e gestire i file di stato.
    2. Cloud Run Invoker: per consentire a Pub/Sub di richiamare la funzione.
    3. Cloud Functions Invoker: per consentire la chiamata di funzioni.
  6. Fai clic su Continua, poi su Fine.

Concedi autorizzazioni IAM sul bucket GCS

  1. Vai a Cloud Storage > Bucket.
  2. Fai clic sul nome del bucket (ad es. forgerock-openidm-audit-logs).
  3. Vai alla scheda Autorizzazioni.
  4. Fai clic su Concedi l'accesso.
  5. Fornisci i seguenti dettagli di configurazione:
    • Aggiungi entità: inserisci l'email del account di servizio (ad es. forgerock-openidm-collector-sa@PROJECT_ID.iam.gserviceaccount.com).
    • Assegna i ruoli: seleziona Storage Object Admin.
  6. Fai clic su Salva.

Crea argomento Pub/Sub

  1. Nella console Google Cloud, vai a Pub/Sub > Argomenti.
  2. Fai clic su Crea argomento.
  3. Fornisci i seguenti dettagli di configurazione:
    • ID argomento: forgerock-openidm-trigger
    • Lascia invariate le altre impostazioni predefinite.
  4. Fai clic su Crea.

Crea una funzione Cloud Run per raccogliere i log

  1. Nella console Google Cloud, vai a Cloud Run.
  2. Fai clic su Crea servizio.
  3. Seleziona Funzione (utilizza un editor in linea per creare una funzione).
  4. Nella sezione Configura, fornisci i seguenti dettagli di configurazione:

    Impostazione Valore
    Nome servizio forgerock-openidm-collector
    Regione Seleziona la regione corrispondente al tuo bucket GCS (ad es. us-central1)
    Tempo di esecuzione Seleziona Python 3.12 o versioni successive.
  5. Nella sezione Trigger:

    1. Fai clic su + Aggiungi trigger.
    2. Seleziona Cloud Pub/Sub.
    3. In Seleziona un argomento Cloud Pub/Sub, scegli forgerock-openidm-trigger.
    4. Fai clic su Salva.
  6. Nella sezione Autenticazione:

    1. Seleziona Richiedi autenticazione.
    2. Controlla Identity and Access Management (IAM).
  7. Scorri verso il basso ed espandi Container, networking, sicurezza.

  8. Vai alla scheda Sicurezza:

    • Service account: seleziona forgerock-openidm-collector-sa.
  9. Vai alla scheda Container:

    1. Fai clic su Variabili e secret.
    2. Fai clic su + Aggiungi variabile per ogni variabile di ambiente:
    Nome variabile Valore di esempio Descrizione
    GCS_BUCKET forgerock-openidm-audit-logs Nome bucket GCS
    GCS_PREFIX openidm Prefisso per i file di log
    STATE_KEY openidm/state.json Percorso file di stato
    OPENIDM_BASE_URL https://openidm.example.com URL di base OpenIDM
    OPENIDM_USERNAME openidm-admin Nome utente amministratore OpenIDM
    OPENIDM_PASSWORD your-admin-password Password amministratore OpenIDM
    AUDIT_TOPICS access,activity,authentication,config,sync Argomenti separati da virgole
    PAGE_SIZE 100 Record per pagina
    MAX_PAGES 50 Numero massimo di pagine per argomento
  10. Nella sezione Richieste:

    • Timeout della richiesta: 600 secondi.
  11. Vai alla scheda Impostazioni:

    • Risorse: 512 MiB di memoria, 1 CPU.
  12. Fai clic su Crea. Una volta creato il servizio, si aprirà l'editor di codice incorporato.

Aggiungi codice per la funzione

  1. Inserisci main nel campo Entry point (Punto di ingresso).
  2. Crea due file nell'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. Fai clic su Esegui il deployment. Il deployment richiede 2-3 minuti.

Crea job Cloud Scheduler

  1. Nella console Google Cloud, vai a Cloud Scheduler.
  2. Fai clic su Crea job.
  3. Fornisci i seguenti dettagli di configurazione:

    Impostazione Valore
    Nome forgerock-openidm-collector-hourly
    Regione Seleziona la stessa regione della funzione Cloud Run
    Frequenza 0 * * * * (ogni ora)
    Fuso orario Seleziona il fuso orario (UTC consigliato)
    Tipo di target Pub/Sub
    Argomento forgerock-openidm-trigger
    Corpo del messaggio {}
  4. Fai clic su Crea.

Opzioni di frequenza di pianificazione

Frequenza Espressione cron Caso d'uso
Ogni 5 minuti */5 * * * * Volume elevato, bassa latenza
Ogni ora 0 * * * * Standard (consigliato)
Ogni giorno 0 0 * * * Raccolta batch

Testare l'integrazione

  1. In Cloud Scheduler, fai clic su Forza esecuzione per il job.
  2. Verifica l'esecuzione nei log di Cloud Run. Cerca: Successfully processed X audit events.
  3. Verifica che esista un nuovo file json nel bucket Cloud Storage nella cartella openidm/.

Recuperare il account di servizio Google SecOps

Configura un feed in Google SecOps

  1. Vai a Impostazioni SIEM > Feed.
  2. Fai clic su Aggiungi nuovo feed > Configura un singolo feed.
  3. Nome feed: ForgeRock OpenIDM Audit Logs.
  4. Tipo di origine: Google Cloud Storage V2.
  5. Log type: FORGEROCK_OPENIDM.
  6. Fai clic su Ottieni service account e copia l'email fornita (ad es. chronicle-12345...).
  7. Fai clic su Avanti.
  8. URL del bucket di archiviazione: gs://forgerock-openidm-audit-logs/openidm/.
  9. Opzione di eliminazione delle fonti: seleziona l'opzione che preferisci (ad es. Mai).
  10. Fai clic su Avanti, rivedi e fai clic su Invia.

Concedi autorizzazioni IAM

  1. Vai a Cloud Storage > Bucket.
  2. Seleziona il bucket e fai clic sulla scheda Autorizzazioni.
  3. Fai clic su Concedi l'accesso.
  4. Aggiungi entità: incolla l'email del account di servizio Google SecOps.
  5. Assegna ruoli: seleziona Visualizzatore oggetti Storage.
  6. Fai clic su Salva.

Tabella di mappatura UDM

Campo log Mappatura UDM Logica
fluenttag_label, topic_label, context_roles_label additional.fields Coppie chiave-valore per il contesto.
Via intermediary.hostname Nome host del proxy/intermediario.
x_forwarded_ip, caller.callerIps intermediary.ip IP dell'intermediario.
timestamp metadata.event_timestamp Timestamp dell'evento.
transactionId metadata.product_deployment_id ID transazione univoco.
eventName metadata.product_event_type Nome evento di ForgeRock.
_id metadata.product_log_id Identificatore univoco del log.
request_method network.http.method Metodo HTTP utilizzato.
response.statusCode network.http.response_code Codice di stato HTTP.
user_agent network.http.user_agent Stringa completa dello user agent.
client.ip, context.ipAddress principal.ip IP di origine dell'attore.
userId, principalData.0 principal.user.userid ID dell'utente che esegue l'azione.
security_action security_result.action Decisione di sicurezza presa.
level security_result.severity Livello di gravità mappato.
server.ip target.ip L'IP del sistema di destinazione.
http.request.path target.url URL/percorso di destinazione.
N/D metadata.product_name Imposta su ForgeRock OpenIDM.
N/D metadata.vendor_name Imposta su ForgeRock.
elapsed_time" and "X-Content-Type-Options additional.fields Mappato dal log delle modifiche
trackingIds.0 metadata.product_log_id Mappato dal log delle modifiche
context.userRolesProperty", "context.authenticationId", and "context.authenticationIdProperty principal.user.attribute.roles Mappato dal log delle modifiche
context.component", "context.moduleId", and "context.queryId principal.resource.attribute.labels Mappato dal log delle modifiche
context.roles", "_normalized.fieldNames", and "_eventId additional.fields Mappato dal log delle modifiche

Log delle modifiche

Visualizza il log delle modifiche per questo parser

Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.