Akamai Cloud Monitor-Logs erfassen
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
- Erstellen Sie einen Amazon S3-Bucket. Folgen Sie dazu dieser Anleitung: Bucket erstellen.
- Speichern Sie den Namen und die Region des Buckets zur späteren Verwendung (z. B.
akamai-cloud-monitor
). - Erstellen Sie einen Nutzer gemäß dieser Anleitung: IAM-Nutzer erstellen.
- Wählen Sie den erstellten Nutzer aus.
- Wählen Sie den Tab Sicherheitsanmeldedaten aus.
- Klicken Sie im Abschnitt Zugriffsschlüssel auf Zugriffsschlüssel erstellen.
- Wählen Sie als Anwendungsfall Drittanbieterdienst aus.
- Klicken Sie auf Weiter.
- Optional: Fügen Sie ein Beschreibungstag hinzu.
- Klicken Sie auf Zugriffsschlüssel erstellen.
- 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.
- Klicken Sie auf Fertig.
- Wählen Sie den Tab Berechtigungen aus.
- Klicken Sie im Bereich Berechtigungsrichtlinien auf Berechtigungen hinzufügen.
- Wählen Sie Berechtigungen hinzufügen aus.
- Wählen Sie Richtlinien direkt anhängen aus.
- Suchen Sie nach der Richtlinie AmazonS3FullAccess und wählen Sie sie aus.
- Klicken Sie auf Weiter.
- Klicken Sie auf Berechtigungen hinzufügen.
IAM-Richtlinie und ‑Rolle für S3-Uploads (Lambda) konfigurieren
- Rufen Sie in der AWS Console IAM > Richtlinien > Richtlinie erstellen > JSON auf und fügen Sie die Richtlinie unten ein.
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/*" } ] }
Klicken Sie auf Weiter > Richtlinie erstellen.
Rufen Sie IAM > Rollen > Rolle erstellen > AWS-Service > Lambda auf.
Hängen Sie die JSON-Richtlinie an.
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 |
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)}), }
Klicken Sie auf Konfiguration > Umgebungsvariablen > Bearbeiten.
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
Rufen Sie Konfiguration > Allgemeine Konfiguration auf.
Klicken Sie auf Bearbeiten und legen Sie Zeitlimit auf 5 Minuten (300 Sekunden) fest.
Klicken Sie auf Speichern.
Amazon API Gateway erstellen (HTTPS-Endpunkt für Akamai)
- Rufen Sie in der AWS Console API Gateway > API erstellen auf.
- Wählen Sie HTTP API > Build (Erstellen) aus.
- 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.
- Integrationen: Wählen Sie Lambda und dann
- 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
- Öffnen Sie in Akamai Control Center Ihre Property in Property Manager.
- Klicken Sie auf Regel hinzufügen > „Cloud-Verwaltung“ auswählen.
- Fügen Sie Cloud Monitor Instrumentation hinzu und wählen Sie die erforderlichen Datasets aus.
- 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>
.
- Hostname für die Bereitstellung: Geben Sie die API Gateway-Aufruf-URL ein (z. B.
- Speichern Sie die Property-Version und aktivieren Sie sie.
Feed in Google SecOps konfigurieren, um Akamai Cloud Monitor (S3 JSON) aufzunehmen
- Rufen Sie die SIEM-Einstellungen > Feeds auf.
- Klicken Sie auf Neuen Feed hinzufügen.
- Geben Sie im Feld Feed name (Feedname) einen Namen für den Feed ein, z. B.
Akamai Cloud Monitor — S3
. - Wählen Sie Amazon S3 V2 als Quelltyp aus.
- Wählen Sie Akamai Cloud Monitor als Logtyp aus.
- Klicken Sie auf Weiter.
- 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
undformat=json
.
- S3-URI:
- Klicken Sie auf Weiter.
- 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