Oracle Cloud Infrastructure-Audit-Logs erfassen

Unterstützt in:

In diesem Dokument wird beschrieben, wie Sie Oracle Cloud Infrastructure-Audit-Logs (OCI) mit einer der folgenden Methoden in Google Security Operations aufnehmen:

  • Methode 1: Cloud Storage: Eine OCI-Funktion schreibt die Logs in einen Cloud Storage-Bucket und ein Google SecOps-Feed liest sie aus dem Bucket.
  • Methode 2: Webhook: Eine OCI-Funktion sendet die Logs direkt an einen Google SecOps-Webhook-Feed. Bei dieser Methode wird kein Cloud Storage-Bucket verwendet.

Bei beiden Methoden wird OCI Connector Hub verwendet, um Audit-Logs an die Funktion zu senden, da OCI Logs nicht direkt an Cloud Storage oder einen HTTPS-Endpunkt senden kann.

Der Oracle Cloud Infrastructure Audit-Dienst zeichnet Aufrufe aller unterstützten öffentlichen OCI-API-Endpunkte automatisch als Logereignisse auf. Alle Dienste unterstützen das Logging durch OCI Audit. Zu den von OCI Audit aufgezeichneten Protokollereignissen gehören API-Aufrufe, die von der OCI-Konsole, der Befehlszeile, SDKs, Ihren eigenen benutzerdefinierten Clients oder anderen OCI-Diensten ausgeführt werden.

Hinweis

Prüfen Sie, ob folgende Voraussetzungen erfüllt sind:

  • Eine Google SecOps-Instanz
  • Privilegierter Zugriff auf die Oracle Cloud Console mit Berechtigungen zum Erstellen und Verwalten von:
    • Connector Hub-Connectors
    • Functions-Anwendungen und -Funktionen
    • IAM-Richtlinien
  • Ein VCN-Subnetz mit Internetzugriff für die OCI-Funktion
  • OCI Cloud Shell oder eine lokale Umgebung mit der Fn-CLI
  • Für Methode 1: Ein Google Cloud -Projekt mit aktivierter Cloud Storage API und Berechtigungen zum Erstellen von Cloud Storage-Buckets, Dienstkonten und IAM-Richtlinien (Identity and Access Management) für Buckets
  • Für Methode 2: Berechtigung zum Erstellen von API-Schlüsseln im Google Cloud -Projekt, das mit Ihrer Google SecOps-Instanz verknüpft ist

Methode 1: Cloud Storage

Cloud Storage-Bucket erstellen

  1. Rufen Sie die Google Cloud Console auf.
  2. Wählen Sie Ihr Projekt aus oder erstellen Sie ein neues.
  3. Rufen Sie im Navigationsmenü Cloud Storage > Buckets auf.
  4. Klicken Sie auf Bucket erstellen.
  5. Geben Sie die folgenden Konfigurationsdetails an:

    Einstellung Wert
    Bucket benennen Geben Sie einen global eindeutigen Namen ein, z. B. oci-audit-logs-gcs.
    Standorttyp Wählen Sie die Option, die am besten zu Ihren Anforderungen passt (Region, Dual-Region, Multi-Region).
    Standort Wählen Sie den Standort aus (z. B. us-central1).
    Speicherklasse Standard (empfohlen für Logs, auf die häufig zugegriffen wird)
    Zugriffssteuerung Einheitlich (empfohlen)
    Schutztools Optional: Objektversionsverwaltung oder Aufbewahrungsrichtlinie aktivieren
  6. Klicken Sie auf Erstellen.

OCI für den Export von Audit-Logs nach Cloud Storage konfigurieren

Oracle Cloud Infrastructure unterstützt den integrierten Export nach Cloud Storage nicht. Sie verwenden den OCI Service Connector Hub mit einer Funktion, um Audit-Logs an Cloud Storage weiterzuleiten.

OCI-Funktion zum Weiterleiten von Logs an Cloud Storage erstellen

  1. Melden Sie sich in der Oracle Cloud Console an.
  2. Gehen Sie zu Entwicklerdienste > Funktionen > Anwendungen.
  3. Wählen Sie das Compartment aus, in dem Sie die Funktionsanwendung erstellen möchten.
  4. Klicken Sie auf Anwendung erstellen.
  5. Geben Sie die folgenden Konfigurationsdetails an:
    • Name: Geben Sie audit-logs-to-gcs-app ein.
    • VCN: Wählen Sie ein Virtual Cloud Network aus.
    • Subnetze: Wählen Sie ein Subnetz mit Internetzugriff aus.
  6. Klicken Sie auf Erstellen.
  7. Nachdem die Anwendung erstellt wurde, klicken Sie auf Getting Started und folgen Sie der Anleitung, um Ihre lokale Entwicklungsumgebung mit der Fn-Befehlszeile einzurichten.
  8. Erstellen Sie auf Ihrem lokalen Computer ein neues Funktionsverzeichnis:

    mkdir oci-audit-to-gcs
    cd oci-audit-to-gcs
    
  9. Initialisieren Sie eine Python-Funktion:

    fn init --runtime python oci-audit-to-gcs
    cd oci-audit-to-gcs
    
  10. Ersetzen Sie den Inhalt von func.py durch den folgenden Code:

    import io
    import json
    import logging
    import os
    from fdk import response
    from google.cloud import storage
    from google.oauth2 import service_account
    from datetime import datetime
    
    # Configure logging
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger()
    
    # Environment variables
    GCS_BUCKET = os.environ.get('GCS_BUCKET')
    GCS_PREFIX = os.environ.get('GCS_PREFIX', 'oci-audit-logs')
    GCS_CREDENTIALS_JSON = os.environ.get('GCS_CREDENTIALS_JSON')
    
    def handler(ctx, data: io.BytesIO = None):
        """
        Oracle Cloud Infrastructure Function to forward Audit logs to GCS.
    
        Args:
            ctx: Function context
            data: Input data containing Audit log events
        """
    
        if not all([GCS_BUCKET, GCS_CREDENTIALS_JSON]):
            logger.error('Missing required environment variables: GCS_BUCKET or GCS_CREDENTIALS_JSON')
            return response.Response(
                ctx, response_data=json.dumps({"error": "Missing configuration"}),
                headers={"Content-Type": "application/json"}
            )
    
        try:
            # Parse input data
            body = json.loads(data.getvalue())
            logger.info(f"Received event: {json.dumps(body)}")
    
            # Extract log entries
            log_entries = []
            if isinstance(body, list):
                log_entries = body
            elif isinstance(body, dict):
                # Service Connector Hub sends data in specific format
                if 'data' in body:
                    log_entries = [body['data']] if isinstance(body['data'], dict) else body['data']
                else:
                    log_entries = [body]
    
            if not log_entries:
                logger.info("No log entries to process")
                return response.Response(
                    ctx, response_data=json.dumps({"status": "no_logs"}),
                    headers={"Content-Type": "application/json"}
                )
    
            # Initialize GCS client with service account credentials
            credentials_dict = json.loads(GCS_CREDENTIALS_JSON)
            credentials = service_account.Credentials.from_service_account_info(credentials_dict)
            storage_client = storage.Client(credentials=credentials, project=credentials_dict.get('project_id'))
            bucket = storage_client.bucket(GCS_BUCKET)
    
            # Write logs to GCS as NDJSON
            timestamp = datetime.utcnow().strftime('%Y%m%d_%H%M%S_%f')
            object_key = f"{GCS_PREFIX}/logs_{timestamp}.ndjson"
            blob = bucket.blob(object_key)
    
            ndjson = '\n'.join([json.dumps(entry, ensure_ascii=False) for entry in log_entries]) + '\n'
            blob.upload_from_string(ndjson, content_type='application/x-ndjson')
    
            logger.info(f"Wrote {len(log_entries)} records to gs://{GCS_BUCKET}/{object_key}")
    
            return response.Response(
                ctx, response_data=json.dumps({"status": "success", "records": len(log_entries)}),
                headers={"Content-Type": "application/json"}
            )
    
        except Exception as e:
            logger.error(f'Error processing logs: {str(e)}')
            return response.Response(
                ctx, response_data=json.dumps({"error": str(e)}),
                headers={"Content-Type": "application/json"},
                status_code=500
            )
    

  11. Aktualisieren Sie requirements.txt mit den folgenden Abhängigkeiten:

    fdk>=0.1.0
    google-cloud-storage>=2.0.0
    google-auth>=2.0.0
    
  12. Stellen Sie die Funktion in OCI bereit:

    fn -v deploy --app audit-logs-to-gcs-app
    
  13. Notieren Sie sich nach Abschluss der Bereitstellung die OCID der Funktion. Sie verwenden es in der nächsten Aufgabe.

Funktionsumgebungsvariablen konfigurieren

  1. Rufen Sie in der Oracle Cloud Console Developer Services > Functions > Applications auf.
  2. Klicken Sie auf die Anwendung (audit-logs-to-gcs-app).
  3. Klicken Sie auf den Funktionsnamen (oci-audit-to-gcs).
  4. Klicken Sie auf Konfiguration.
  5. Fügen Sie die folgenden Konfigurationsvariablen hinzu:

    Schlüssel Wert
    GCS_BUCKET Name Ihres Cloud Storage-Bucket (z. B. oci-audit-logs-gcs)
    GCS_PREFIX Präfix für Logdateien (z. B. oci-audit-logs)
    GCS_CREDENTIALS_JSON JSON-String des Dienstkontoschlüssels von Google Cloud (siehe unten)
  6. Klicken Sie auf Änderungen speichern.

Google Cloud -Dienstkonto für die OCI-Funktion erstellen

Die OCI-Funktion benötigt ein Google Cloud -Dienstkonto, um in den Cloud Storage-Bucket schreiben zu können.

  1. Wechseln Sie in der Google Cloud Console zu IAM & Verwaltung > Dienstkonten.
  2. Klicken Sie auf Dienstkonto erstellen.
  3. Geben Sie die folgenden Konfigurationsdetails an:
    • Dienstkontoname: Geben Sie oci-function-gcs-writer ein.
    • Beschreibung des Dienstkontos: Geben Sie Service account for OCI Function to write Audit logs to GCS ein.
  4. Klicken Sie auf Erstellen und fortfahren.
  5. Fügen Sie im Abschnitt Diesem Dienstkonto Zugriff auf das Projekt erteilen die folgende Rolle hinzu:
    1. Klicken Sie auf Rolle auswählen.
    2. Suchen Sie nach Storage Object Admin und wählen Sie die Rolle aus.
  6. Klicken Sie auf Weiter.
  7. Klicken Sie auf Fertig.
  8. Klicken Sie auf die E-Mail-Adresse des neu erstellten Dienstkontos.
  9. Rufen Sie den Tab Schlüssel auf.
  10. Klicken Sie auf Schlüssel hinzufügen > Neuen Schlüssel erstellen.
  11. Wählen Sie JSON als Schlüsseltyp aus.
  12. Klicken Sie auf Erstellen.
  13. Die JSON-Schlüsseldatei wird auf Ihren Computer heruntergeladen.
  14. Öffnen Sie die JSON-Schlüsseldatei und kopieren Sie den gesamten Inhalt.
  15. Kehren Sie zur Funktionskonfiguration der Oracle Cloud Console zurück.
  16. Fügen Sie den JSON-Inhalt in die Konfigurationsvariable GCS_CREDENTIALS_JSON ein.

IAM-Berechtigungen für den Cloud Storage-Bucket gewähren

Gewähren Sie dem Dienstkonto Schreibberechtigungen für den Cloud Storage-Bucket:

  1. Rufen Sie Cloud Storage > Buckets auf.
  2. Klicken Sie auf den Namen Ihres Buckets (oci-audit-logs-gcs).
  3. Wechseln Sie zum Tab Berechtigungen.
  4. Klicken Sie auf Zugriff erlauben.
  5. Geben Sie die folgenden Konfigurationsdetails an:
    • Hauptkonten hinzufügen: Geben Sie die E-Mail-Adresse des Dienstkontos (oci-function-gcs-writer@PROJECT_ID.iam.gserviceaccount.com) ein.
    • Rollen zuweisen: Wählen Sie Storage Object Admin aus.
  6. Klicken Sie auf Speichern.

OCI Service Connector Hub erstellen

  1. Melden Sie sich in der Oracle Cloud Console an.
  2. Rufen Sie Observability & Management > Logging > Service Connector Hub auf.
  3. Wählen Sie das Compartment aus, in dem Sie den Dienst-Connector erstellen möchten.
  4. Klicken Sie auf Service Connector erstellen.
  5. Geben Sie die folgenden Konfigurationsdetails an:

    • Informationen zum Service Connector:

      Einstellung Wert
      Connector-Name audit-logs-to-gcs-connector eingeben
      Beschreibung Forward OCI Audit logs to Cloud Storage eingeben
      Ressourcenfach Fach auswählen
    • Quelle konfigurieren:

      Einstellung Wert
      Quelle Wählen Sie Logging aus.
      Fach Wählen Sie das Compartment mit den Audit-Logs aus.
      Loggruppe Wählen Sie _Audit (Standard-Loggruppe für Audit-Logs) aus.
  6. Klicken Sie auf + Weiteres Protokoll.

  7. Wählen Sie das Audit-Log für Ihr Compartment aus (z. B. _Audit_Include_Subcompartment).

    • Ziel konfigurieren:

      Einstellung Wert
      Ziel- Wählen Sie Funktionen aus.
      Funktionsfach Wählen Sie das Compartment aus, das die Funktion enthält.
      Funktionsanwendung audit-logs-to-gcs-app auswählen
      Funktion oci-audit-to-gcs auswählen
  8. Gehen Sie zu Aufgabe konfigurieren (optional) und übernehmen Sie die Standardeinstellungen.

  9. Klicken Sie auf Erstellen.

IAM-Richtlinie für den Service Connector Hub erstellen

Der Service Connector Hub benötigt Berechtigungen zum Aufrufen der Funktion, die Sie so erstellen:

  1. Rufen Sie in der Oracle Cloud Console Identity & Security > Policies auf.
  2. Wählen Sie das Compartment aus, in dem Sie den Service Connector Hub erstellt haben.
  3. Klicken Sie auf Richtlinie erstellen.
  4. Geben Sie die folgenden Konfigurationsdetails an:
    • Name: Geben Sie service-connector-functions-policy ein.
    • Beschreibung: Geben Sie Allow Service Connector Hub to invoke Functions ein.
    • Spezifikation: Wählen Sie die Spezifikation aus.
  5. Aktivieren Sie im Bereich Richtlinienerstellung die Option Manuellen Editor anzeigen.
  6. Geben Sie die folgenden Richtlinienanweisungen ein:

    Allow any-user to use fn-function in compartment <compartment-name> where all {request.principal.type='serviceconnector'}
    Allow any-user to use fn-invocation in compartment <compartment-name> where all {request.principal.type='serviceconnector'}
    
    • Ersetzen Sie <compartment-name> durch den Namen Ihres Fachs.
  7. Klicken Sie auf Erstellen.

Integration testen

  1. Melden Sie sich in der Oracle Cloud Console an.
  2. Führen Sie einige Aktionen aus, die Audit-Logs generieren (z. B. Erstellen oder Ändern einer Ressource).
  3. Warten Sie 2–5 Minuten, bis die Protokolle verarbeitet wurden.
  4. Rufen Sie in der Google Cloud Console Cloud Storage > Buckets auf.
  5. Klicken Sie auf den Namen Ihres Buckets (oci-audit-logs-gcs).
  6. Rufen Sie den Präfixordner (oci-audit-logs/) auf.
  7. Prüfen Sie, ob neue .ndjson-Dateien im Bucket angezeigt werden.

Google SecOps-Dienstkonto abrufen

Google SecOps verwendet ein eindeutiges Dienstkonto, um Daten aus Ihrem Cloud Storage-Bucket zu lesen. Sie müssen diesem Dienstkonto Zugriff auf Ihren Bucket gewähren.

E‑Mail-Adresse des Dienstkontos abrufen

  1. Rufen Sie die SIEM-Einstellungen > Feeds auf.
  2. Klicken Sie auf Neuen Nachrichten-Feed hinzufügen.
  3. Klicken Sie auf Einzelnen Feed konfigurieren.
  4. Geben Sie im Feld Feedname einen Namen für den Feed ein, z. B. Oracle Cloud Audit Logs.
  5. Wählen Sie Google Cloud Storage V2 als Quelltyp aus.
  6. Wählen Sie Oracle Cloud Infrastructure-Audit-Logs als Logtyp aus.
  7. Klicken Sie auf Dienstkonto abrufen. Eine eindeutige E-Mail-Adresse für das Dienstkonto wird angezeigt, z. B.:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  8. Kopieren Sie diese E-Mail-Adresse, um sie im nächsten Schritt zu verwenden.

Dem Google SecOps-Dienstkonto IAM-Berechtigungen gewähren

Das Google SecOps-Dienstkonto benötigt zwei Rollen für Ihren Cloud Storage-Bucket: „Storage-Objekt-Betrachter“ zum Lesen der Logobjekte und eine Rolle auf Bucket-Ebene zum Lesen der Bucket-Metadaten.

  1. Rufen Sie Cloud Storage > Buckets auf.
  2. Klicken Sie auf den Namen Ihres Buckets (oci-audit-logs-gcs).
  3. Wechseln Sie zum Tab Berechtigungen.
  4. Klicken Sie auf Zugriff erlauben.
  5. Geben Sie die folgenden Konfigurationsdetails an:
    • Hauptkonten hinzufügen: Fügen Sie die E-Mail-Adresse des Google SecOps-Dienstkontos ein.
    • Rollen zuweisen: Wählen Sie die beiden folgenden Rollen aus:
    • Storage-Objekt-Betrachter: Liest die Logobjekte.
    • Storage Legacy Bucket Reader: Liest die Bucket-Metadaten. Wenn Sie die Löschoption Übertragene Dateien und leere Verzeichnisse löschen ausgewählt haben, wählen Sie stattdessen Storage Legacy Bucket Writer aus. Dadurch wird auch die Löschberechtigung gewährt.
  6. Klicken Sie auf Speichern.

Feed in Google SecOps konfigurieren, um OCI-Audit-Logs aufzunehmen

  1. Rufen Sie die SIEM-Einstellungen > Feeds auf.
  2. Klicken Sie auf Neuen Nachrichten-Feed hinzufügen.
  3. Klicken Sie auf Einzelnen Feed konfigurieren.
  4. Geben Sie im Feld Feedname einen Namen für den Feed ein, z. B. Oracle Cloud Audit Logs.
  5. Wählen Sie Google Cloud Storage V2 als Quelltyp aus.
  6. Wählen Sie Oracle Cloud Infrastructure-Audit-Logs als Logtyp aus.
  7. Klicken Sie auf Weiter.
  8. Geben Sie Werte für die folgenden Eingabeparameter an:

    • Storage-Bucket-URL: Geben Sie den Cloud Storage-Bucket-URI mit dem Präfixpfad ein:
    gs://oci-audit-logs-gcs/oci-audit-logs/
    
    • Ersetzen Sie:

      • oci-audit-logs-gcs: Name Ihres Cloud Storage-Bucket.
      • oci-audit-logs: Optionales Präfix oder Pfad, in dem Logs gespeichert werden (leer lassen für Stammverzeichnis).

      Beispiele:

      • Root-Bucket: gs://company-logs/
      • Mit Präfix: gs://company-logs/oci-audit-logs/
      • Mit Unterordner: gs://company-logs/oracle/audit/

    • Option zum Löschen der Quelle: Wählen Sie die gewünschte Löschoption aus:

      • Dateien nie löschen: Dateien werden nie aus der Quelle gelöscht (empfohlen für Tests).
      • Übertragene Dateien und leere Verzeichnisse löschen: Dateien und leere Verzeichnisse werden nach einem erfolgreichen Abruf aus der Quelle gelöscht.
    • Maximales Dateialter: Dateien einschließen, die in den letzten Tagen geändert wurden. Der Standardwert ist 180 Tage.

    • Asset-Namespace: Der Asset-Namespace.

    • Aufnahmelabels: Das Label, das auf die Ereignisse aus diesem Feed angewendet werden soll.

  9. Klicken Sie auf Weiter.

  10. Prüfen Sie die neue Nachrichten-Feed-Konfiguration auf dem Bildschirm Abschließen und klicken Sie dann auf Senden.

Methode 2: Webhook

Bei dieser Methode liefert Connector Hub Batches von Audit-Logeinträgen an eine OCI-Funktion, die sie dann über HTTPS an einen Google SecOps-Webhook-Feed sendet. Es ist kein Cloud Storage-Bucket beteiligt.

Webhook-Feed in Google SecOps erstellen

Feed erstellen

  1. Rufen Sie die SIEM-Einstellungen > Feeds auf.
  2. Klicken Sie auf Neuen Nachrichten-Feed hinzufügen.
  3. Klicken Sie auf der nächsten Seite auf Einzelnen Feed konfigurieren.
  4. Geben Sie im Feld Feedname einen Namen für den Feed ein, z. B. OCI Audit Logs Webhook.
  5. Wählen Sie Webhook als Quelltyp aus.
  6. Wählen Sie Oracle Cloud Infrastructure-Audit-Logs als Logtyp aus.
  7. Klicken Sie auf Weiter.
  8. Geben Sie Werte für die folgenden Eingabeparameter an:
    • Trennzeichen für Aufteilung: Geben Sie \n ein. Die Funktion sendet jeden Logeintrag in einer eigenen Zeile.
    • Asset-Namespace: Der Asset-Namespace.
    • Aufnahmelabels: Das Label, das auf die Ereignisse aus diesem Feed angewendet werden soll.
  9. Klicken Sie auf Weiter.
  10. Prüfen Sie die neue Nachrichten-Feed-Konfiguration auf dem Bildschirm Abschließen und klicken Sie dann auf Senden.

Secret-Schlüssel generieren und speichern

  1. Klicken Sie auf der Feed-Detailseite auf Geheimen Schlüssel generieren.
  2. Kopieren Sie den geheimen Schlüssel und speichern Sie ihn an einem sicheren Ort.

Feed-Endpunkt-URL abrufen

  1. Gehen Sie zum Tab Details des Feeds.
  2. Kopieren Sie im Abschnitt Endpunktinformationen die Feed-Endpunkt-URL. Die URL hat folgendes Format:

    https://<REGION>-chronicle.googleapis.com/v1alpha/projects/<PROJECT_NUMBER>/locations/<REGION>/instances/<INSTANCE_ID>/feeds/<FEED_ID>:importPushLogs
    
  3. Klicken Sie auf Fertig.

Google Cloud -API-Schlüssel erstellen

  1. Rufen Sie in der Google Cloud Console die Seite „Anmeldedaten“ auf.
  2. Wählen Sie das Projekt aus, das mit Ihrer Google SecOps-Instanz verknüpft ist.
  3. Klicken Sie auf Anmeldedaten erstellen > API-Schlüssel.
  4. Klicken Sie auf API-Schlüssel bearbeiten, um den Schlüssel einzuschränken.
  5. Geben Sie im Feld Name einen aussagekräftigen Namen ein, z. B. oci-audit-webhook.
  6. Wählen Sie unter API-Einschränkungen die Option Schlüssel einschränken und dann in der Liste APIs auswählen die Option Chronicle API aus.
  7. Klicken Sie auf Speichern.
  8. Kopieren Sie den API-Schlüsselwert und speichern Sie ihn an einem sicheren Ort.

OCI-Funktion zum Weiterleiten von Logs an den Webhook erstellen

Anwendung erstellen

  1. Melden Sie sich in der Oracle Cloud Console an.
  2. Öffnen Sie das Navigationsmenü und wählen Sie Entwicklerdienste > Funktionen > Anwendungen aus.
  3. Wählen Sie das Compartment aus, in dem Sie die Funktionsanwendung erstellen möchten.
  4. Klicken Sie auf Anwendung erstellen.
  5. Geben Sie die folgenden Konfigurationsdetails an:
    • Name: Geben Sie audit-logs-to-secops-app ein.
    • VCN: Wählen Sie ein Virtual Cloud Network aus.
    • Subnetze: Wählen Sie ein Subnetz mit Internetzugriff aus: ein öffentliches Subnetz mit einem Internet-Gateway oder ein privates Subnetz mit einem NAT-Gateway. Die Funktion muss den Google SecOps-Endpunkt über HTTPS (Port 443) erreichen.
  6. Klicken Sie auf Erstellen.

Funktion erstellen und bereitstellen

  1. Nachdem die Anwendung erstellt wurde, klicken Sie auf Erste Schritte und folgen Sie der Anleitung, um die OCI Cloud Shell oder Ihre lokale Entwicklungsumgebung mit der Fn-Befehlszeile einzurichten.
  2. Initialisieren Sie eine Python-Funktion:

    fn init --runtime python oci-audit-to-secops
    cd oci-audit-to-secops
    
  3. Ersetzen Sie den Inhalt von func.py durch den folgenden Code:

    import io
    import json
    import logging
    import os
    import random
    import time
    from email.utils import parsedate_to_datetime
    
    import requests
    from fdk import response
    
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger()
    
    # The webhook accepts at most 4 MB per request and 1 MB per log line.
    # Connector Hub delivers batches of up to 6 MB, so a batch is sent as several
    # requests, each made of whole log entries.
    MAX_REQUEST_BYTES = 3 * 1024 * 1024
    MAX_LINE_BYTES = 1024 * 1024
    
    MAX_ATTEMPTS = 5
    RETRYABLE_STATUS = {429, 500, 502, 503, 504}
    # OCI stops the function at its configured timeout (300 seconds). Stop retrying
    # early enough to fail cleanly so that Connector Hub retries the whole batch.
    DEADLINE_SECONDS = 240
    
    def to_lines(body):
        """Serialize each log entry from the Connector Hub batch as one JSON line."""
        entries = body if isinstance(body, list) else [body]
        lines = []
        for entry in entries:
            line = json.dumps(entry, ensure_ascii=False, separators=(',', ':')).encode('utf-8')
            if len(line) > MAX_LINE_BYTES:
                entry_id = entry.get('id') if isinstance(entry, dict) else None
                logger.error(f'Skipping log entry {entry_id}: {len(line)} bytes exceeds the 1 MB line limit')
                continue
            lines.append(line)
        return lines
    
    def to_requests(lines):
        """Group whole lines into newline-delimited request bodies below MAX_REQUEST_BYTES."""
        chunk, size = [], 0
        for line in lines:
            if chunk and size + len(line) + 1 > MAX_REQUEST_BYTES:
                yield b'\n'.join(chunk), len(chunk)
                chunk, size = [], 0
            chunk.append(line)
            size += len(line) + 1
        if chunk:
            yield b'\n'.join(chunk), len(chunk)
    
    def retry_after_seconds(value):
        """Parse a Retry-After header given either in seconds or as an HTTP date."""
        if not value:
            return None
        try:
            return max(0.0, float(value))
        except ValueError:
            pass
        try:
            return max(0.0, parsedate_to_datetime(value).timestamp() - time.time())
        except (TypeError, ValueError, IndexError, OverflowError):
            return None
    
    def post(session, url, headers, payload, deadline):
        """Send one request, retrying throttling and server errors until the deadline."""
        status, detail = None, ''
        for attempt in range(1, MAX_ATTEMPTS + 1):
            remaining = deadline - time.monotonic()
            if remaining < 5:
                break
            wait = None
            try:
                resp = session.post(url, data=payload, headers=headers, timeout=(10, min(60, remaining)))
            except requests.RequestException as e:
                status, detail = None, str(e)
            else:
                if 200 <= resp.status_code < 300:
                    return
                status, detail = resp.status_code, resp.text[:500]
                if status not in RETRYABLE_STATUS:
                    raise RuntimeError(f'Webhook rejected the request with HTTP {status}: {detail}')
                wait = retry_after_seconds(resp.headers.get('Retry-After'))
            if wait is None:
                wait = min(30, 2 ** attempt) + random.uniform(0, 1)
            if attempt == MAX_ATTEMPTS or time.monotonic() + wait >= deadline:
                break
            logger.warning(f'Attempt {attempt} failed (HTTP {status}): {detail}. Retrying in {wait:.1f} seconds')
            time.sleep(wait)
        raise RuntimeError(f'Webhook request failed (HTTP {status}): {detail}')
    
    def handler(ctx, data: io.BytesIO = None):
        """Forward a Connector Hub batch of OCI Audit log entries to the webhook feed.
    
        Any exception fails the invocation, and Connector Hub then retries the batch.
        """
        deadline = time.monotonic() + DEADLINE_SECONDS
    
        url = os.environ.get('SECOPS_WEBHOOK_URL')
        api_key = os.environ.get('SECOPS_API_KEY')
        secret_key = os.environ.get('SECOPS_SECRET_KEY')
        if not all([url, api_key, secret_key]):
            raise RuntimeError('Missing configuration: SECOPS_WEBHOOK_URL, SECOPS_API_KEY and SECOPS_SECRET_KEY are required')
    
        raw = data.getvalue() if data else b''
        if not raw.strip():
            logger.info('Received an empty batch')
            return response.Response(
                ctx, response_data=json.dumps({'records': 0}),
                headers={'Content-Type': 'application/json'}
            )
    
        lines = to_lines(json.loads(raw))
        headers = {
            'Content-Type': 'application/json',
            'X-goog-api-key': api_key,
            'X-Webhook-Access-Key': secret_key,
        }
    
        sent = 0
        with requests.Session() as session:
            for payload, count in to_requests(lines):
                post(session, url, headers, payload, deadline)
                sent += count
    
        logger.info(f'Forwarded {sent} log entries')
        return response.Response(
            ctx, response_data=json.dumps({'records': sent}),
            headers={'Content-Type': 'application/json'}
        )
    

  4. Ersetzen Sie den Inhalt von requirements.txt durch die folgenden Abhängigkeiten:

    fdk>=0.1.0
    requests>=2.32.0
    
  5. Öffnen Sie func.yaml und fügen Sie die folgende Zeile hinzu, um das Zeitlimit für die Funktion von den standardmäßigen 30 Sekunden auf maximal 300 Sekunden zu erhöhen:

    timeout: 300
    
  6. Stellen Sie die Funktion in OCI bereit:

    fn -v deploy --app audit-logs-to-secops-app
    

Funktionsumgebungsvariablen konfigurieren

  1. Rufen Sie in der Oracle Cloud Console die Seite Developer Services > Functions > Applications auf.
  2. Klicken Sie auf die Anwendung (audit-logs-to-secops-app).
  3. Klicken Sie auf den Funktionsnamen (oci-audit-to-secops).
  4. Klicken Sie auf Konfiguration.
  5. Fügen Sie die folgenden Konfigurationsvariablen hinzu:

    Schlüssel Wert
    SECOPS_WEBHOOK_URL Die URL des Feed-Endpunkts
    SECOPS_API_KEY Der API-Schlüssel für Google Cloud
    SECOPS_SECRET_KEY Der geheime Schlüssel des Feeds
  6. Klicken Sie auf Änderungen speichern.

Funktionslogs aktivieren

  1. Wählen Sie auf der Listenseite Anwendungen die Option audit-logs-to-secops-app aus.
  2. Wählen Sie den Tab Monitoring aus und rufen Sie den Abschnitt Logs auf.
  3. Wählen Sie im Menü Aktionen (Dreipunkt-Menü) für die Kategorie Funktionsaufruf-Logs die Option Log aktivieren aus.
  4. Behalten Sie das Standard-Compartment, die Standard-Loggruppe und den Standard-Lognamen bei oder ändern Sie sie nach Bedarf.
  5. Wählen Sie Protokoll aktivieren aus.

OCI Connector Hub-Connector erstellen

  1. Öffnen Sie das Navigationsmenü und wählen Sie Analytics und KI aus. Wählen Sie unter Messaging die Option Connector Hub aus.
  2. Wählen Sie das Compartment aus, in dem Sie den Connector erstellen möchten.
  3. Klicken Sie auf Connector erstellen.
  4. Geben Sie die folgenden Konfigurationsdetails an:

    • Connector-Informationen:

      Einstellung Wert
      Connector-Name audit-logs-to-secops-connector eingeben
      Beschreibung Forward OCI Audit logs to a webhook feed eingeben
      Ressourcenfach Fach auswählen
    • Quelle konfigurieren:

      Einstellung Wert
      Quelle Wählen Sie Logging aus.
      Fach Wählen Sie das Compartment mit den Audit-Logs aus.
      Loggruppe Wählen Sie _Audit (Standard-Loggruppe für Audit-Logs) aus.
  5. Klicken Sie auf + Weiteres Protokoll.

  6. Wählen Sie das Audit-Log für Ihr Compartment aus (z. B. _Audit_Include_Subcompartment).

    • Ziel konfigurieren:

      Einstellung Wert
      Ziel- Wählen Sie Funktionen aus.
      Funktionsfach Wählen Sie das Compartment aus, das die Funktion enthält.
      Funktionsanwendung audit-logs-to-secops-app auswählen
      Funktion oci-audit-to-secops auswählen
  7. Gehen Sie zu Aufgabe konfigurieren (optional) und übernehmen Sie die Standardeinstellungen.

  8. Wenn Sie aufgefordert werden, eine Richtlinie zu erstellen (erforderlich für den Zugriff zum Erstellen oder Aktualisieren eines Dienst-Connectors), wählen Sie Erstellen aus.

  9. Klicken Sie auf Erstellen.

IAM-Richtlinie für Connector Hub erstellen

Connector Hub benötigt Berechtigungen, um die Funktion aufzurufen.

  1. Rufen Sie in der Oracle Cloud Console Identity & Security > Policies auf.
  2. Wählen Sie das Compartment aus, in dem Sie den Connector erstellt haben.
  3. Klicken Sie auf Richtlinie erstellen.
  4. Geben Sie die folgenden Konfigurationsdetails an:
    • Name: Geben Sie connector-hub-secops-function-policy ein.
    • Beschreibung: Geben Sie Allow Connector Hub to invoke the webhook forwarding function ein.
    • Spezifikation: Wählen Sie die Spezifikation aus.
  5. Aktivieren Sie im Bereich Richtlinienerstellung die Option Manuellen Editor anzeigen.
  6. Geben Sie die folgenden Richtlinienanweisungen ein:

    Allow any-user to use fn-function in compartment <compartment-name> where all {request.principal.type='serviceconnector'}
    Allow any-user to use fn-invocation in compartment <compartment-name> where all {request.principal.type='serviceconnector'}
    
  7. Klicken Sie auf Erstellen.

Wie die Funktion Logs liefert

  • Batchgröße: Connector Hub sendet der Funktion Batches mit einer Größe von bis zu 6 MB und der Webhook akzeptiert bis zu 4 MB pro Anfrage. Die Funktion teilt jeden Batch in Anfragen von bis zu 3 MB auf. Die Aufteilung erfolgt nur zwischen Logeinträgen, nie innerhalb eines Eintrags. Jeder Eintrag kommt als ein Ereignis in Google SecOps an.
  • Wiederholungen: Die Funktion wiederholt HTTP-429- und 5xx-Antworten mit exponentiellem Backoff und berücksichtigt den Header Retry-After. Bei jedem anderen Fehler oder bei einer Anfrage, die nach fünf Versuchen immer noch fehlschlägt, schlägt der Aufruf fehl. Connector Hub wiederholt dann den gesamten Batch und verschiebt keine späteren Batches, bis der Vorgang erfolgreich ist.
  • Aufbewahrung: Die Logging-Quelle von Connector Hub speichert nicht zugestellte Daten 24 Stunden lang. Wenn die Zustellung länger fehlschlägt, gehen die ältesten nicht zugestellten Logs verloren. Beheben Sie daher Fehler, die im Funktionslog gemeldet werden, umgehend.
  • Duplikate: Connector Hub liefert jeden Batch mindestens einmal. Wenn ein Batch wiederholt wird, nachdem ein Teil davon bereits gesendet wurde, kann Google SecOps diese Einträge zweimal empfangen.
  • Zu große Einträge: Ein Logeintrag, der größer als 1 MB ist, überschreitet das Webhook-Zeilenlimit. Die Funktion überspringt sie und schreibt ihre ID in das Funktionslog.

Einbindung verifizieren

So prüfen Sie die Integration:

  1. Führen Sie in der Oracle Cloud Console einige Aktionen aus, die Audit-Logs generieren (z. B. Erstellen oder Ändern einer Ressource).
  2. Warten Sie 2–5 Minuten, bis Connector Hub die Protokolle bereitgestellt hat.
  3. Öffnen Sie das von Ihnen aktivierte Funktionsaufruf-Log und prüfen Sie, ob es Forwarded N log entries-Nachrichten enthält. Eine Fehlermeldung enthält den von Google SecOps zurückgegebenen HTTP-Status.
  4. Führen Sie in Google SecOps eine Suche nach Rohprotokollen für den Protokolltyp OCI_AUDIT durch und prüfen Sie, ob die Audit-Ereignisse ankommen.

UDM-Zuordnungstabelle

Logfeld UDM-Zuordnung Logik
accept_encoding_field additional.fields Zusammengeführt
accept_field additional.fields Zusammengeführt
additional_app additional.fields Zusammengeführt
additional_content_type additional.fields Zusammengeführt
additional_sort_by additional.fields Zusammengeführt
additionaldetails_data additional.fields Zusammengeführt
allow_methods_field additional.fields Zusammengeführt
auth_type_label additional.fields Zusammengeführt
authorization_field additional.fields Zusammengeführt
backend_connect_time_field additional.fields Zusammengeführt
backend_processing_time_field additional.fields Zusammengeführt
caller_id_label additional.fields Zusammengeführt
caller_name_label additional.fields Zusammengeführt
cloud_event_versiom_field additional.fields Zusammengeführt
compartment_id_field additional.fields Zusammengeführt
compartment_name_field additional.fields Zusammengeführt
connection_field additional.fields Zusammengeführt
content_length_field additional.fields Zusammengeführt
content_type_field additional.fields Zusammengeführt
event_grouping_id_field additional.fields Zusammengeführt
event_name_label additional.fields Zusammengeführt
event_resource_label additional.fields Zusammengeführt
event_source_label additional.fields Zusammengeführt
event_type_label additional.fields Zusammengeführt
event_type_versiom_field additional.fields Zusammengeführt
has_compariment_id additional.fields Zugeordnet: true → additional_app
has_sort_by additional.fields Zugeordnet: true → additional_sort_by
listener_name_field additional.fields Zusammengeführt
log_group_id_field additional.fields Zusammengeführt
log_id_field additional.fields Zusammengeführt
message additional.fields Zugeordnete Werte (insgesamt 41, z.B. \/ → tenant_id_label, \/ → auth_type_label, \/ → `ca...
opc_request_id_field additional.fields Zusammengeführt
origin_field additional.fields Zusammengeführt
param0_field additional.fields Zusammengeführt
param1_field additional.fields Zusammengeführt
referer_field additional.fields Zusammengeführt
request_processing_time_field additional.fields Zusammengeführt
resource_id_field additional.fields Zusammengeführt
routing_rules_engine_errors_field additional.fields Zusammengeführt
routing_rules_matched_rule_field additional.fields Zusammengeführt
routing_rules_rule_hits_field additional.fields Zusammengeführt
routing_rules_rule_misses_field additional.fields Zusammengeführt
source_field additional.fields Zusammengeführt
tenant_id_label additional.fields Zusammengeführt
column3 extensions.auth.type Zugeordnet: login successful → AUTHTYPE_UNSPECIFIED
message extensions.auth.type Zugeordnet: \/ → AUTHTYPE_UNSPECIFIED
column3 metadata.description Direkt zugeordnet
data.message metadata.description Direkt zugeordnet
column1 metadata.event_timestamp Geparst als yyyy-MM-dd HH:mm:ss
data_event_time metadata.event_timestamp Geparst als yyyy-MM-ddTHH:mm:ss.SSSSSSZ
time metadata.event_timestamp Geparst als ISO8601
metadata_event_type metadata.event_type Direkt zugeordnet
type metadata.product_event_type Direkt zugeordnet
data_event_id metadata.product_log_id Direkt zugeordnet
id metadata.product_log_id Direkt zugeordnet
message metadata.product_name Zugeordnet: \/ → OCI_AUDIT
specversion metadata.product_version Direkt zugeordnet
message metadata.vendor_name Zugeordnet: \/ → Oracle
message network.application_protocol Zugeordnet: \/ → HTTPS, \/ → HTTP
protocol network.application_protocol Zugeordnet: (?i)HTTPS → HTTPS, (?i)HTTP → HTTP
version network.application_protocol_version Direkt zugeordnet
data_request_action network.http.method Direkt zugeordnet
method network.http.method Direkt zugeordnet
data_identity_userAgent network.http.parsed_user_agent Umbenannt/zugeordnet
data_request_agent network.http.parsed_user_agent Umbenannt/zugeordnet
url network.http.referral_url Direkt zugeordnet
data.backendStatusCode network.http.response_code Direkt zugeordnet
data_response_status network.http.response_code Umbenannt/zugeordnet
data.userAgent network.http.user_agent Direkt zugeordnet
data_identity_userAgent network.http.user_agent Direkt zugeordnet
data_request_agent network.http.user_agent Direkt zugeordnet
data.receivedBytes network.received_bytes Direkt zugeordnet
message network.received_bytes Zugeordnet: \/ → uinteger
data.sentBytes network.sent_bytes Direkt zugeordnet
message network.sent_bytes Zugeordnet: \/ → uinteger
data_identity_consoleSessionId network.session_id Umbenannt/zugeordnet
data.sslCipher network.tls.cipher Direkt zugeordnet
data.sslProtocol network.tls.version Direkt zugeordnet
data.host principal.asset.hostname Direkt zugeordnet
hostname principal.asset.hostname Direkt zugeordnet
column6 principal.asset.ip Zusammengeführt
data.forwardedForAddr principal.asset.ip Zusammengeführt
data_identity_ipAddress principal.asset.ip Zugeordnet: ^(?:[0-9]{1,3}[.]){3}[0-9]{1,3}$ → data_identity_ipAddress
data_request_origin principal.asset.ip Zusammengeführt
ip1 principal.asset.ip Zusammengeführt
ip2 principal.asset.ip Zusammengeführt
message principal.asset.ip Zugeordnete Werte (insgesamt 7, z.B. \/ → column6, \/ → data_request_origin, \/ → ip2)
src_ip principal.asset.ip Zusammengeführt
data.host principal.hostname Direkt zugeordnet
hostname principal.hostname Direkt zugeordnet
column6 principal.ip Zusammengeführt
data.forwardedForAddr principal.ip Zusammengeführt
data_identity_ipAddress principal.ip Zugeordnet: ^(?:[0-9]{1,3}[.]){3}[0-9]{1,3}$ → data_identity_ipAddress
data_request_origin principal.ip Zusammengeführt
ip1 principal.ip Zusammengeführt
ip2 principal.ip Zusammengeführt
message principal.ip Zugeordnete Werte (insgesamt 7, z.B. \/ → column6, \/ → data_request_origin, \/ → ip2)
src_ip principal.ip Zusammengeführt
data_request_headers_sec-ch-ua-platform_0 principal.platform Zugeordnet: (?i)Linux → LINUX, (?i)windows → WINDOWS, (?i)mac/ios → MAC
message principal.platform Zugeordnet: \/ → LINUX, \/ → WINDOWS, \/ → MAC
originalConnection.sourcePort principal.port Direkt zugeordnet
src_port principal.port Direkt zugeordnet
data_request_headers_oci-original-url_0 principal.url Direkt zugeordnet
credentials_label principal.user.attribute.labels Zusammengeführt
message principal.user.attribute.labels Zugeordnet: \/ → credentials_label
data.identity.principalName principal.user.user_display_name Direkt zugeordnet
data.username principal.user.user_display_name Direkt zugeordnet
data.identity.principalId principal.user.userid Direkt zugeordnet
data.principalId principal.user.userid Direkt zugeordnet
column3 security_result Zugeordnet: login successful → security_result
message security_result Zugeordnet: \/ → security_result
allow_action security_result.action Zusammengeführt
column3 security_result.action Zugeordnet: login successful → allow_action
message security_result.action Zugeordnet: \/ → allow_action
credential_type_field security_result.detection_fields Zusammengeführt
message security_result.detection_fields Zugeordnet: \/ → credential_type_field
data.response.message security_result.summary Direkt zugeordnet
message target.asset.ip Zugeordnet: \/ → originalConnection.destinationIp, \/ → tar_ip
originalConnection.destinationIp target.asset.ip Zusammengeführt
tar_ip target.asset.ip Zusammengeführt
message target.ip Zugeordnet: \/ → originalConnection.destinationIp, \/ → tar_ip
originalConnection.destinationIp target.ip Zusammengeführt
tar_ip target.ip Zusammengeführt
originalConnection.destinationPort target.port Direkt zugeordnet
tar_port target.port Direkt zugeordnet
message target.resource.attribute.labels Zugeordnet: \/ → namespace_label
namespace_label target.resource.attribute.labels Zusammengeführt
type target.resource.attribute.labels Zugeordnet: listretentionrules → namespace_label
data.resourceId target.resource.name Direkt zugeordnet
data.resourceName target.resource.name Direkt zugeordnet
bucketId target.resource.product_object_id Direkt zugeordnet
data.resourceId target.resource.product_object_id Direkt zugeordnet
data_request_id target.resource.product_object_id Direkt zugeordnet
message target.resource.resource_type Zugeordnet: \/ → STORAGE_BUCKET
type target.resource.resource_type Zugeordnet: listretentionrules → STORAGE_BUCKET
data_request_path target.url Direkt zugeordnet
column2 target.user.email_addresses Zusammengeführt
message target.user.email_addresses Zugeordnet: \/ → column2
– extensions.auth.type Konstante: AUTHTYPE_UNSPECIFIED
– metadata.product_name Konstante: OCI_AUDIT
– metadata.vendor_name Konstante: Oracle
– network.application_protocol Konstante: HTTPS
– principal.platform Konstante: LINUX
– target.resource.resource_type Konstante: STORAGE_BUCKET

Änderungsprotokoll

Änderungsprotokoll für diesen Parser ansehen

Benötigen Sie weitere Hilfe? Antworten von Community-Mitgliedern und Google SecOps-Experten erhalten