Mengumpulkan log Akamai Cloud Monitor
Dokumen ini menjelaskan cara menyerap log Akamai Cloud Monitor (Load Balancer, Traffic Shaper, ADC) ke Google Security Operations menggunakan AWS S3. Akamai mengirimkan peristiwa JSON ke endpoint HTTPS Anda; penerima API Gateway + Lambda menulis peristiwa ke S3 (JSONL, gz). Parser mengubah log JSON menjadi UDM. Fungsi ini mengekstrak kolom dari payload JSON, melakukan konversi jenis data, mengganti nama kolom agar sesuai dengan skema UDM, dan menangani logika tertentu untuk kolom kustom dan pembuatan URL. Hal ini juga menggabungkan penanganan error dan logika bersyarat berdasarkan keberadaan kolom.
Sebelum memulai
Pastikan Anda memenuhi prasyarat berikut:
- Instance Google SecOps
- Akses istimewa ke Akamai Control Center dan Property Manager
- Akses istimewa ke AWS*(S3, IAM, Lambda, API Gateway)
Mengonfigurasi bucket AWS S3 dan IAM untuk Google SecOps
- Buat bucket Amazon S3 dengan mengikuti panduan pengguna ini: Membuat bucket
- Simpan Name dan Region bucket untuk referensi di masa mendatang (misalnya,
akamai-cloud-monitor
). - Buat pengguna dengan mengikuti panduan pengguna ini: Membuat pengguna IAM.
- Pilih Pengguna yang dibuat.
- Pilih tab Kredensial keamanan.
- Klik Create Access Key di bagian Access Keys.
- Pilih Layanan pihak ketiga sebagai Kasus penggunaan.
- Klik Berikutnya.
- Opsional: tambahkan tag deskripsi.
- Klik Create access key.
- Klik Download CSV file untuk menyimpan Access Key dan Secret Access Key untuk digunakan nanti.
- Klik Selesai.
- Pilih tab Izin.
- Klik Tambahkan izin di bagian Kebijakan izin.
- Pilih Tambahkan izin.
- Pilih Lampirkan kebijakan secara langsung
- Telusuri dan pilih kebijakan AmazonS3FullAccess.
- Klik Berikutnya.
- Klik Add permissions.
Mengonfigurasi kebijakan dan peran IAM untuk upload S3 (Lambda)
- Di Konsol AWS, buka IAM > Policies > Create policy > JSON, lalu tempel kebijakan di bawah.
Kebijakan JSON (ganti
akamai-cloud-monitor
dengan nama bucket S3 Anda):{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowPutAkamaiObjects", "Effect": "Allow", "Action": ["s3:PutObject"], "Resource": "arn:aws:s3:::akamai-cloud-monitor/*" } ] }
Klik Berikutnya > Buat kebijakan.
Buka IAM > Roles > Create role > AWS service > Lambda.
Lampirkan kebijakan JSON.
Beri nama peran
WriteAkamaiCMToS3Role
, lalu klik Buat peran.
Buat fungsi Lambda
Setelan | Nilai |
---|---|
Nama | akamai_cloud_monitor_to_s3 |
Runtime | Python 3.13 |
Arsitektur | x86_64 |
Peran eksekusi | WriteAkamaiCMToS3Role |
Setelah fungsi dibuat, buka tab Code, hapus stub, dan masukkan kode berikut (
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)}), }
Buka Configuration > Environment variables > Edit.
Klik Tambahkan variabel lingkungan baru, lalu tetapkan nilai berikut:
Variabel lingkungan
Kunci Contoh S3_BUCKET_NAME
akamai-cloud-monitor
S3_PREFIX
akamai/cloud-monitor/json/
INGEST_TOKEN
random-shared-secret
Buka Konfigurasi > Konfigurasi umum.
Klik Edit, lalu tetapkan Waktu tunggu ke 5 menit (300 detik).
Klik Simpan.
Buat Amazon API Gateway (endpoint HTTPS untuk Akamai)
- Di AWS Console, buka API Gateway > Create API.
- Pilih HTTP API > Build.
- Berikan detail konfigurasi berikut:
- Integrations: Pilih Lambda, lalu pilih
akamai_cloud_monitor_to_s3
. - Rute: Tambahkan
/{proxy+}
ANY atau buat rute tertentu (misalnya, POST/akamai/cloud-monitor
). - Tahapan: Buat atau gunakan $default.
- Integrations: Pilih Lambda, lalu pilih
- Deploy API dan salin Invoke URL (misalnya,
https://abc123.execute-api.<region>.amazonaws.com
).
Mengonfigurasi Akamai Cloud Monitor untuk mengirimkan log
- Di Akamai Control Center, buka Property Anda di Property Manager.
- Klik Tambahkan Aturan > pilih Pengelolaan Cloud.
- Tambahkan Cloud Monitor Instrumentation dan pilih Datasets yang diperlukan.
- Tambahkan Pengiriman Data Cloud Monitor.
- Nama Host Pengiriman: masukkan URL Pemanggilan API Gateway (misalnya,
abc123.execute-api.<region>.amazonaws.com
). - Jalur URL Penayangan: rute plus token kueri opsional, misalnya:
/akamai/cloud-monitor?token=<INGEST_TOKEN>
.
- Nama Host Pengiriman: masukkan URL Pemanggilan API Gateway (misalnya,
- Simpan dan Aktifkan versi properti.
Mengonfigurasi feed di Google SecOps untuk memproses Akamai Cloud Monitor (JSON S3)
- Buka Setelan SIEM > Feed.
- Klik Tambahkan Feed Baru.
- Di kolom Nama feed, masukkan nama untuk feed (misalnya,
Akamai Cloud Monitor — S3
). - Pilih Amazon S3 V2 sebagai Jenis sumber.
- Pilih Akamai Cloud Monitor sebagai Jenis log.
- Klik Berikutnya.
- Tentukan nilai untuk parameter input berikut:
- URI S3:
s3://akamai-cloud-monitor/akamai/cloud-monitor/json/
- Opsi penghapusan sumber: Apakah akan menghapus file dan/atau direktori setelah ditransfer.
- Usia File Maksimum: Menyertakan file yang diubah dalam beberapa hari terakhir. Defaultnya adalah 180 hari.
- ID Kunci Akses: Kunci akses akun alfanumerik 20 karakter (misalnya, AKIAIOSFODNN7EXAMPLE).
- Kunci Akses Rahasia: Kunci akses rahasia akun alfanumerik 40 karakter (misalnya, wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY).
- Namespace aset:
akamai.cloud_monitor
- Label penyerapan: Label ditambahkan ke semua peristiwa dari feed ini (misalnya,
source=akamai_cloud_monitor
,format=json
).
- URI S3:
- Klik Berikutnya.
- Tinjau konfigurasi feed baru Anda di layar Selesaikan, lalu klik Kirim.
Tabel Pemetaan UDM
Kolom Log | Pemetaan UDM | Logika |
---|---|---|
accLang |
network.http.user_agent |
Dipetakan secara langsung jika bukan "-" atau string kosong. |
city |
principal.location.city |
Dipetakan secara langsung jika bukan "-" atau string kosong. |
cliIP |
principal.ip |
Dipetakan secara langsung jika bukan string kosong. |
country |
principal.location.country_or_region |
Dipetakan secara langsung jika bukan "-" atau string kosong. |
cp |
additional.fields |
Dipetakan sebagai pasangan nilai kunci dengan kunci "cp". |
customField |
about.ip , about.labels , src.ip |
Diuraikan sebagai pasangan nilai kunci. Penanganan khusus untuk "eIp" dan "pIp" untuk dipetakan ke src.ip dan about.ip . Kunci lainnya dipetakan sebagai label dalam about . |
errorCode |
security_result.summary , security_result.severity |
Jika ada, menetapkan security_result.severity ke "ERROR" dan memetakan nilai ke security_result.summary . |
geo.city |
principal.location.city |
Dipetakan secara langsung jika city adalah "-" atau string kosong. |
geo.country |
principal.location.country_or_region |
Dipetakan secara langsung jika country adalah "-" atau string kosong. |
geo.lat |
principal.location.region_latitude |
Dipetakan secara langsung, dikonversi menjadi float. |
geo.long |
principal.location.region_longitude |
Dipetakan secara langsung, dikonversi menjadi float. |
geo.region |
principal.location.state |
Dipetakan secara langsung. |
id |
metadata.product_log_id |
Dipetakan secara langsung jika bukan string kosong. |
message.cliIP |
principal.ip |
Dipetakan secara langsung jika cliIP adalah string kosong. |
message.fwdHost |
principal.hostname |
Dipetakan secara langsung. |
message.reqHost |
target.hostname , target.url |
Digunakan untuk membuat target.url dan mengekstrak target.hostname . |
message.reqLen |
network.sent_bytes |
Dipetakan secara langsung, dikonversi menjadi bilangan bulat tidak bertanda jika totalBytes kosong atau "-". |
message.reqMethod |
network.http.method |
Dipetakan secara langsung jika reqMethod adalah string kosong. |
message.reqPath |
target.url |
Ditambahkan ke target.url . |
message.reqPort |
target.port |
Dipetakan secara langsung, dikonversi menjadi bilangan bulat jika reqPort adalah string kosong. |
message.respLen |
network.received_bytes |
Dipetakan secara langsung, dikonversi menjadi bilangan bulat yang tidak bertanda tangan. |
message.sslVer |
network.tls.version |
Dipetakan secara langsung. |
message.status |
network.http.response_code |
Dipetakan secara langsung, dikonversi menjadi bilangan bulat jika statusCode kosong atau "-". |
message.UA |
network.http.user_agent |
Dipetakan secara langsung jika UA adalah "-" atau string kosong. |
network.asnum |
additional.fields |
Dipetakan sebagai pasangan nilai kunci dengan kunci "asnum". |
network.edgeIP |
intermediary.ip |
Dipetakan secara langsung. |
network.network |
additional.fields |
Dipetakan sebagai pasangan nilai kunci dengan kunci "network". |
network.networkType |
additional.fields |
Dipetakan sebagai pasangan nilai kunci dengan kunci "networkType". |
proto |
network.application_protocol |
Digunakan untuk menentukan network.application_protocol . |
queryStr |
target.url |
Ditambahkan ke target.url jika bukan "-" atau string kosong. |
referer |
network.http.referral_url , about.hostname |
Dipetakan secara langsung jika bukan "-". Nama host yang diekstrak dipetakan ke about.hostname . |
reqHost |
target.hostname , target.url |
Digunakan untuk membuat target.url dan mengekstrak target.hostname . |
reqId |
metadata.product_log_id , network.session_id |
Dipetakan secara langsung jika id adalah string kosong. Juga dipetakan ke network.session_id . |
reqMethod |
network.http.method |
Dipetakan secara langsung jika bukan string kosong. |
reqPath |
target.url |
Ditambahkan ke target.url jika bukan "-". |
reqPort |
target.port |
Dipetakan langsung, dikonversi menjadi bilangan bulat. |
reqTimeSec |
metadata.event_timestamp , timestamp |
Digunakan untuk menyetel stempel waktu peristiwa. |
start |
metadata.event_timestamp , timestamp |
Digunakan untuk menyetel stempel waktu peristiwa jika reqTimeSec adalah string kosong. |
statusCode |
network.http.response_code |
Dipetakan secara langsung, dikonversi menjadi bilangan bulat jika bukan "-" atau string kosong. |
tlsVersion |
network.tls.version |
Dipetakan secara langsung. |
totalBytes |
network.sent_bytes |
Dipetakan secara langsung, dikonversi menjadi bilangan bulat tidak bertanda jika tidak kosong atau "-". |
type |
metadata.product_event_type |
Dipetakan secara langsung. |
UA |
network.http.user_agent |
Dipetakan secara langsung jika bukan "-" atau string kosong. |
version |
metadata.product_version |
Dipetakan secara langsung. |
xForwardedFor |
principal.ip |
Dipetakan secara langsung jika bukan "-" atau string kosong. |
(Logika Parser) | metadata.vendor_name |
Ditetapkan ke "Akamai". |
(Logika Parser) | metadata.product_name |
Tetapkan ke "DataStream". |
(Logika Parser) | metadata.event_type |
Disetel ke "NETWORK_HTTP". |
(Logika Parser) | metadata.product_version |
Ditetapkan ke "2" jika version adalah string kosong. |
(Logika Parser) | metadata.log_type |
Tetapkan ke "AKAMAI_CLOUD_MONITOR". |
(Logika Parser) | network.application_protocol |
Ditentukan dari proto atau message.proto . Disetel ke "HTTPS" jika salah satunya berisi "HTTPS" (tidak peka huruf besar/kecil), "HTTP" jika tidak. |
(Logika Parser) | security_result.severity |
Disetel ke "INFORMATIONAL" jika errorCode adalah "-" atau string kosong. |
(Logika Parser) | target.url |
Dibuat dari protocol , reqHost (atau message.reqHost ), reqPath (atau message.reqPath ), dan queryStr . |
Perlu bantuan lain? Dapatkan jawaban dari anggota Komunitas dan profesional Google SecOps.