Akamai Cloud Monitor-Logs erfassen

Unterstützt in:

In diesem Dokument wird beschrieben, wie Sie Akamai Cloud Monitor-Logs (Load Balancer, Traffic Shaper, ADC) mit AWS S3 in Google Security Operations aufnehmen. Akamai sendet JSON-Ereignisse an Ihren HTTPS-Endpunkt. Ein API Gateway + Lambda-Empfänger schreibt die Ereignisse in S3 (JSONL, gz). Der Parser wandelt die JSON-Logs in UDM um. Es werden Felder aus der JSON-Nutzlast extrahiert, Datentypkonvertierungen durchgeführt, Felder umbenannt, damit sie dem UDM-Schema entsprechen, und bestimmte Logik für benutzerdefinierte Felder und die URL-Erstellung wird berücksichtigt. Außerdem enthält sie Fehlerbehandlung und bedingte Logik basierend auf dem Vorhandensein von Feldern.

Hinweise

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

  • Google SecOps-Instanz
  • Privilegierter Zugriff auf Akamai Control Center und Property Manager
  • Privilegierter Zugriff auf AWS*(S3, IAM, Lambda, API Gateway)

AWS S3-Bucket und IAM für Google SecOps konfigurieren

  1. Erstellen Sie einen Amazon S3-Bucket. Folgen Sie dazu dieser Anleitung: Bucket erstellen.
  2. Speichern Sie den Namen und die Region des Buckets zur späteren Verwendung (z. B. akamai-cloud-monitor).
  3. Erstellen Sie einen Nutzer gemäß dieser Anleitung: IAM-Nutzer erstellen.
  4. Wählen Sie den erstellten Nutzer aus.
  5. Wählen Sie den Tab Sicherheitsanmeldedaten aus.
  6. Klicken Sie im Abschnitt Zugriffsschlüssel auf Zugriffsschlüssel erstellen.
  7. Wählen Sie als Anwendungsfall Drittanbieterdienst aus.
  8. Klicken Sie auf Weiter.
  9. Optional: Fügen Sie ein Beschreibungstag hinzu.
  10. Klicken Sie auf Zugriffsschlüssel erstellen.
  11. Klicken Sie auf CSV-Datei herunterladen, um den Access Key (Zugriffsschlüssel) und den Secret Access Key (geheimer Zugriffsschlüssel) zur späteren Verwendung zu speichern.
  12. Klicken Sie auf Fertig.
  13. Wählen Sie den Tab Berechtigungen aus.
  14. Klicken Sie im Bereich Berechtigungsrichtlinien auf Berechtigungen hinzufügen.
  15. Wählen Sie Berechtigungen hinzufügen aus.
  16. Wählen Sie Richtlinien direkt anhängen aus.
  17. Suchen Sie nach der Richtlinie AmazonS3FullAccess und wählen Sie sie aus.
  18. Klicken Sie auf Weiter.
  19. Klicken Sie auf Berechtigungen hinzufügen.

IAM-Richtlinie und ‑Rolle für S3-Uploads (Lambda) konfigurieren

  1. Rufen Sie in der AWS Console IAM > Richtlinien > Richtlinie erstellen > JSON auf und fügen Sie die Richtlinie unten ein.
  2. JSON-Richtlinie (ersetzen Sie akamai-cloud-monitor durch den Namen Ihres S3-Buckets):

    {
    "Version": "2012-10-17",
    "Statement": [
        {
        "Sid": "AllowPutAkamaiObjects",
        "Effect": "Allow",
        "Action": ["s3:PutObject"],
        "Resource": "arn:aws:s3:::akamai-cloud-monitor/*"
        }
    ]
    }
    
  3. Klicken Sie auf Weiter > Richtlinie erstellen.

  4. Rufen Sie IAM > Rollen > Rolle erstellen > AWS-Service > Lambda auf.

  5. Hängen Sie die JSON-Richtlinie an.

  6. Geben Sie der Rolle den Namen WriteAkamaiCMToS3Role und klicken Sie auf Rolle erstellen.

Lambda-Funktion erstellen

Einstellung Wert
Name akamai_cloud_monitor_to_s3
Laufzeit Python 3.13
Architektur x86_64
Ausführungsrolle WriteAkamaiCMToS3Role
  1. Nachdem die Funktion erstellt wurde, öffnen Sie den Tab Code, löschen Sie den Stub und geben Sie den folgenden Code ein (akamai_cloud_monitor_to_s3.py):

    #!/usr/bin/env python3
    # Lambda: Receive Akamai Cloud Monitor POST, write JSONL (gz) to S3
    
    import os, json, gzip, io, uuid, base64, datetime as dt
    import boto3
    
    S3_BUCKET  = os.environ["S3_BUCKET_NAME"]
    S3_PREFIX  = os.environ.get("S3_PREFIX", "akamai/cloud-monitor/json/").strip("/") + "/"
    INGEST_TOKEN = os.environ.get("INGEST_TOKEN")  # optional shared secret in URL query (?token=...)
    
    s3 = boto3.client("s3")
    
    def _write_jsonl_gz(objs: list) -> str:
        key = f"{dt.datetime.utcnow():%Y/%m/%d}/akamai-cloud-monitor-{uuid.uuid4()}.json.gz"
        buf = io.BytesIO()
        with gzip.GzipFile(fileobj=buf, mode="w") as gz:
            for o in objs:
                gz.write((json.dumps(o, separators=(",", ":")) + "n").encode())
        buf.seek(0)
        s3.upload_fileobj(
            buf,
            S3_BUCKET,
            f"{S3_PREFIX}{key}",
            ExtraArgs={
                "ContentType": "application/json",
                "ContentEncoding": "gzip",
            },
        )
        return f"s3://{S3_BUCKET}/{S3_PREFIX}{key}"
    
    def _parse_records_from_event(event) -> list:
        # HTTP API (Lambda proxy) event: body is a JSON string
        body = event.get("body") or ""
        if event.get("isBase64Encoded"):
            body = base64.b64decode(body).decode("utf-8", "replace")
        try:
            data = json.loads(body)
        except Exception:
            # accept line-delimited JSON as pass-through
            try:
                return [json.loads(line) for line in body.splitlines() if line.strip()]
            except Exception:
                return []
        if isinstance(data, list):
            return data
        if isinstance(data, dict):
            return [data]
        return []
    
    def lambda_handler(event, context=None):
        # Optional shared-secret verification via query parameter (?token=...)
        if INGEST_TOKEN:
            qs = event.get("queryStringParameters") or {}
            token = qs.get("token")
            if token != INGEST_TOKEN:
                return {"statusCode": 403, "body": "forbidden"}
    
        records = _parse_records_from_event(event)
        if not records:
            return {"statusCode": 204, "body": "no content"}
    
        key = _write_jsonl_gz(records)
        return {
            "statusCode": 200,
            "headers": {"Content-Type": "application/json"},
            "body": json.dumps({"ok": True, "s3_key": key, "count": len(records)}),
        }
    
  2. Klicken Sie auf Konfiguration > Umgebungsvariablen > Bearbeiten.

  3. Klicken Sie auf Neue Umgebungsvariable hinzufügen und legen Sie die folgenden Werte fest:

    Umgebungsvariablen

    Schlüssel Beispiel
    S3_BUCKET_NAME akamai-cloud-monitor
    S3_PREFIX akamai/cloud-monitor/json/
    INGEST_TOKEN random-shared-secret
  4. Rufen Sie Konfiguration > Allgemeine Konfiguration auf.

  5. Klicken Sie auf Bearbeiten und legen Sie Zeitlimit auf 5 Minuten (300 Sekunden) fest.

  6. Klicken Sie auf Speichern.

Amazon API Gateway erstellen (HTTPS-Endpunkt für Akamai)

  1. Rufen Sie in der AWS Console API Gateway > API erstellen auf.
  2. Wählen Sie HTTP API > Build (Erstellen) aus.
  3. Geben Sie die folgenden Konfigurationsdetails an:
    • Integrationen: Wählen Sie Lambda und dann akamai_cloud_monitor_to_s3 aus.
    • Routen: Fügen Sie BELIEBIGE /{proxy+} hinzu oder erstellen Sie eine bestimmte Route (z. B. POST /akamai/cloud-monitor).
    • Phasen: Erstellen oder verwenden Sie $default.
  4. Stellen Sie die API bereit und kopieren Sie die Invoke URL (z. B. https://abc123.execute-api.<region>.amazonaws.com).

Akamai Cloud Monitor zum Senden von Logs konfigurieren

  1. Öffnen Sie in Akamai Control Center Ihre Property in Property Manager.
  2. Klicken Sie auf Regel hinzufügen > „Cloud-Verwaltung“ auswählen.
  3. Fügen Sie Cloud Monitor Instrumentation hinzu und wählen Sie die erforderlichen Datasets aus.
  4. Fügen Sie Cloud Monitor Data Delivery hinzu.
    • Hostname für die Bereitstellung: Geben Sie die API Gateway-Aufruf-URL ein (z. B. abc123.execute-api.<region>.amazonaws.com).
    • Auslieferungs-URL-Pfad: Ihre Route plus ein optionales Abfrage-Token, z. B. /akamai/cloud-monitor?token=<INGEST_TOKEN>.
  5. Speichern Sie die Property-Version und aktivieren Sie sie.

Feed in Google SecOps konfigurieren, um Akamai Cloud Monitor (S3 JSON) aufzunehmen

  1. Rufen Sie die SIEM-Einstellungen > Feeds auf.
  2. Klicken Sie auf Neuen Feed hinzufügen.
  3. Geben Sie im Feld Feed name (Feedname) einen Namen für den Feed ein, z. B. Akamai Cloud Monitor — S3.
  4. Wählen Sie Amazon S3 V2 als Quelltyp aus.
  5. Wählen Sie Akamai Cloud Monitor als Logtyp aus.
  6. Klicken Sie auf Weiter.
  7. Geben Sie Werte für die folgenden Eingabeparameter an:
    • S3-URI: s3://akamai-cloud-monitor/akamai/cloud-monitor/json/
    • Optionen zum Löschen der Quelle: Gibt an, ob Dateien und/oder Verzeichnisse nach der Übertragung gelöscht werden sollen.
    • Maximales Dateialter: Enthält Dateien, die in den letzten Tagen geändert wurden. Der Standardwert ist 180 Tage.
    • Zugriffsschlüssel-ID: Ein 20-stelliger alphanumerischer Zugriffsschlüssel für das Konto (z.B. AKIAIOSFODNN7EXAMPLE).
    • Secret-Zugriffsschlüssel: Ein 40-stelliger alphanumerischer Secret-Zugriffsschlüssel für das Konto (z.B. wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY).
    • Asset-Namespace: akamai.cloud_monitor
    • Labels für die Datenaufnahme: Alle Ereignisse aus diesem Feed werden mit Labels versehen, z. B. source=akamai_cloud_monitor und format=json.
  8. Klicken Sie auf Weiter.
  9. Prüfen Sie die neue Feedkonfiguration auf dem Bildschirm Abschließen und klicken Sie dann auf Senden.

UDM-Zuordnungstabelle

Logfeld UDM-Zuordnung Logik
accLang network.http.user_agent Direkt zugeordnet, wenn nicht „-“ oder leerer String.
city principal.location.city Direkt zugeordnet, wenn nicht „-“ oder leerer String.
cliIP principal.ip Wird direkt zugeordnet, wenn es sich nicht um einen leeren String handelt.
country principal.location.country_or_region Direkt zugeordnet, wenn nicht „-“ oder leerer String.
cp additional.fields Als Schlüssel/Wert-Paar mit dem Schlüssel „cp“ zugeordnet.
customField about.ip, about.labels, src.ip Als Schlüssel/Wert-Paare geparst. Sonderbehandlung für „eIp“ und „pIp“, um sie src.ip bzw. about.ip zuzuordnen. Andere Schlüssel werden als Labels in about zugeordnet.
errorCode security_result.summary, security_result.severity Falls vorhanden, wird security_result.severity auf „ERROR“ gesetzt und der Wert wird security_result.summary zugeordnet.
geo.city principal.location.city Direkt zugeordnet, wenn city „-“ oder ein leerer String ist.
geo.country principal.location.country_or_region Direkt zugeordnet, wenn country „-“ oder ein leerer String ist.
geo.lat principal.location.region_latitude Direkt zugeordnet, in Gleitkommazahl konvertiert.
geo.long principal.location.region_longitude Direkt zugeordnet, in Gleitkommazahl konvertiert.
geo.region principal.location.state Direkt zugeordnet.
id metadata.product_log_id Wird direkt zugeordnet, wenn es sich nicht um einen leeren String handelt.
message.cliIP principal.ip Wird direkt zugeordnet, wenn cliIP ein leerer String ist.
message.fwdHost principal.hostname Direkt zugeordnet.
message.reqHost target.hostname, target.url Wird zum Erstellen von target.url und zum Extrahieren von target.hostname verwendet.
message.reqLen network.sent_bytes Direkt zugeordnet, in eine vorzeichenlose Ganzzahl konvertiert, wenn totalBytes leer oder „-“ ist.
message.reqMethod network.http.method Wird direkt zugeordnet, wenn reqMethod ein leerer String ist.
message.reqPath target.url An target.url angehängt.
message.reqPort target.port Direkt zugeordnet, in eine Ganzzahl konvertiert, wenn reqPort ein leerer String ist.
message.respLen network.received_bytes Direkt zugeordnet, in eine vorzeichenlose Ganzzahl konvertiert.
message.sslVer network.tls.version Direkt zugeordnet.
message.status network.http.response_code Direkt zugeordnet, in eine Ganzzahl konvertiert, wenn statusCode leer oder „-“ ist.
message.UA network.http.user_agent Direkt zugeordnet, wenn UA „-“ oder ein leerer String ist.
network.asnum additional.fields Als Schlüssel/Wert-Paar mit dem Schlüssel „asnum“ zugeordnet.
network.edgeIP intermediary.ip Direkt zugeordnet.
network.network additional.fields Als Schlüssel/Wert-Paar mit dem Schlüssel „network“ zugeordnet.
network.networkType additional.fields Als Schlüssel/Wert-Paar mit dem Schlüssel „networkType“ zugeordnet.
proto network.application_protocol Wird zur Bestimmung von network.application_protocol verwendet.
queryStr target.url Wird an target.url angehängt, wenn es sich nicht um „-“ oder einen leeren String handelt.
referer network.http.referral_url, about.hostname Direkt zugeordnet, wenn nicht „-“. Der extrahierte Hostname wird about.hostname zugeordnet.
reqHost target.hostname, target.url Wird zum Erstellen von target.url und zum Extrahieren von target.hostname verwendet.
reqId metadata.product_log_id, network.session_id Wird direkt zugeordnet, wenn id ein leerer String ist. Auch network.session_id zugeordnet.
reqMethod network.http.method Wird direkt zugeordnet, wenn es sich nicht um einen leeren String handelt.
reqPath target.url Wird an target.url angehängt, wenn nicht „-“ angegeben ist.
reqPort target.port Direkt zugeordnet, in eine Ganzzahl konvertiert.
reqTimeSec metadata.event_timestamp, timestamp Wird verwendet, um den Zeitstempel des Ereignisses festzulegen.
start metadata.event_timestamp, timestamp Wird verwendet, um den Ereigniszeitstempel festzulegen, wenn reqTimeSec ein leerer String ist.
statusCode network.http.response_code Direkt zugeordnet, in eine Ganzzahl konvertiert, wenn nicht „-“ oder ein leerer String.
tlsVersion network.tls.version Direkt zugeordnet.
totalBytes network.sent_bytes Direkt zugeordnet, in eine vorzeichenlose Ganzzahl konvertiert, wenn nicht leer oder „-“.
type metadata.product_event_type Direkt zugeordnet.
UA network.http.user_agent Direkt zugeordnet, wenn nicht „-“ oder leerer String.
version metadata.product_version Direkt zugeordnet.
xForwardedFor principal.ip Direkt zugeordnet, wenn nicht „-“ oder leerer String.
(Parserlogik) metadata.vendor_name Legen Sie diesen Wert auf „Akamai“ fest.
(Parserlogik) metadata.product_name Legen Sie diesen Wert auf „DataStream“ fest.
(Parserlogik) metadata.event_type Legen Sie diesen Wert auf „NETWORK_HTTP“ fest.
(Parserlogik) metadata.product_version Wird auf „2“ gesetzt, wenn version ein leerer String ist.
(Parserlogik) metadata.log_type Legen Sie diesen Wert auf „AKAMAI_CLOUD_MONITOR“ fest.
(Parserlogik) network.application_protocol Wird aus proto oder message.proto ermittelt. Wird auf „HTTPS“ festgelegt, wenn eine der beiden URLs „HTTPS“ (unabhängig von der Groß-/Kleinschreibung) enthält, andernfalls auf „HTTP“.
(Parserlogik) security_result.severity Auf „INFORMATIONAL“ setzen, wenn errorCode „-“ oder ein leerer String ist.
(Parserlogik) target.url Besteht aus protocol, reqHost (oder message.reqHost), reqPath (oder message.reqPath) und queryStr.

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