איסוף יומנים של Akamai Enterprise Application Access
גרסת כלי הניתוח: 3.0
במאמר הזה מוסבר איך להטמיע יומנים של Akamai Enterprise Application Access (EAA) ב-Google Security Operations באמצעות Akamai Unified Log Streamer (ULS) ו-Bindplane. Akamai EAA הוא פתרון גישה לרשת במודל אבטחה של אפס אמון, שמספק גישה מאובטחת ומבוססת-זהות לאפליקציות ארגוניות בלי VPN רגיל. מערכת EAA מפיקה נתונים תפעוליים בצורה של יומני גישה, יומני ביקורת של אדמינים, מדדי תקינות של מחברים, מלאי מכשירים ומידע על תקינות הספרייה. הכלי לניתוח מחלץ שדות מיומני ה-JSON, מבצע טרנספורמציות של נתונים כמו המרות של מחרוזות וחילוץ של כתובות IP, וממפה את השדות האלה ל-UDM. הוא מטפל בסוגים שונים של אירועים, כולל NETWORK_HTTP ו-USER_UNCATEGORIZED, על סמך הנוכחות של שדות ספציפיים.
לפני שמתחילים
חשוב לוודא שיש לכם את הדברים הבאים:
- מופע של Google SecOps.
- מארח Windows Server 2016 ואילך, או מארח Linux עם
systemdלהפעלת הסוכן של Bindplane. - מארח Linux עם Python 3.9 ואילך, או סביבה בקונטיינר (Docker או Kubernetes) להרצת Unified Log Streamer.
- אם אתם מפעילים את הסוכן מאחורי שרת proxy, ודאו שהיציאות של חומת האש פתוחות בהתאם לדרישות של סוכן Bindplane.
- דייר Akamai EAA עם הרשאת אדמין.
פרטי הכניסה ל-API של Akamai:
- לגישה ולפידים של ביקורת אדמין: מפתח וסוד של EAA Legacy API (נוצר במרכז Enterprise).
- לפידים של תקינות המחבר, מלאי המכשירים ותקינות הספרייה: פרטי כניסה ל-Akamai OPEN API (אימות EdgeGrid) עם גישת קריאה וכתיבה ל-Enterprise Application Access API.
קבלת פרטי כניסה ל-Google SecOps בשביל סוכן Bindplane
כדי לאמת את סוכן Bindplane ב-Google SecOps, בוחרים באחת מהשיטות הבאות:
- פריסות חדשות: משתמשים ב-Chronicle API (אפשרות 1).
- פריסות קודמות: ממשיכים להשתמש בקובץ האימות להטמעת נתונים (אפשרות 2) עד שה-Ingestion API יופסק ב-20 ביולי 2027.
אפשרות 1: יצירת חשבון שירות ל-Chronicle API (מומלץ)
- נכנסים למסוףGoogle Cloud ובוחרים את הפרויקט ב- Google Cloud שמקושר למכונה של Google SecOps.
- נכנסים לדף IAM & Admin > Service Accounts.
- לוחצים על Create service account.
- מספקים את פרטי ההגדרה הבאים:
- שם חשבון השירות: מזינים שם לחשבון (לדוגמה,
bindplane-ingest). - Service account description: מזינים תיאור (לדוגמה,
Bindplane agent log ingestion).
- שם חשבון השירות: מזינים שם לחשבון (לדוגמה,
- לוחצים על Create and continue.
- בקטע Grant this service account access to project, לוחצים על Select a role ובוחרים באפשרות Chronicle Editor.
- לוחצים על המשך ואז על סיום.
- לוחצים על חשבון השירות שיצרתם ואז עוברים לכרטיסייה Keys.
- לוחצים על Add key > Create new key.
- בוחרים באפשרות JSON ולוחצים על Create. קובץ המפתח יורד למחשב.
- שומרים את קובץ המפתח בתור
ingestion-auth.jsonבספריית ה-collector של Bindplane (/opt/observiq-otel-collector/ingestion-auth.jsonב-Linux אוC:\Program Files\observIQ OpenTelemetry Collector\ingestion-auth.jsonב-Windows), או מעדכנים אתcreds_file_pathב-config.yamlכך שיתאים לנתיב שבו שמרתם אותו. - עוברים אל IAM & Admin > Settings ומעתיקים את הערך של Project number. תצטרכו אותו כדי להגדיר את הייצוא.
אפשרות 2: הורדת קובץ אימות להטמעת נתונים (גרסה מדור קודם)
- נכנסים למסוף Google SecOps.
- עוברים אל הגדרות SIEM > סוכני איסוף.
- מורידים את קובץ האימות להטמעת נתונים.
- שומרים את הקובץ בצורה מאובטחת במערכת שבה יותקן סוכן Bindplane.
איך מקבלים את מספר הלקוח ב-Google SecOps
- נכנסים למסוף Google SecOps.
- עוברים אל SIEM Settings > Profile.
- מעתיקים את מספר הלקוח מהקטע פרטי הארגון ושומרים אותו.
התקנת הסוכן של Bindplane
מתקינים את הסוכן של Bindplane במערכת ההפעלה Windows או Linux לפי ההוראות הבאות.
התקנת חלונות
- פותחים את שורת הפקודה או את PowerShell כאדמין.
מריצים את הפקודה הבאה:
msiexec /i "https://github.com/observIQ/bindplane-agent/releases/latest/download/observiq-otel-collector.msi" /quiet
התקנה ב-Linux
- פותחים טרמינל עם הרשאות root או sudo.
מריצים את הפקודה הבאה:
sudo sh -c "$(curl -fsSlL https://github.com/observiq/bindplane-agent/releases/latest/download/install_unix.sh)" install_unix.sh
מקורות מידע נוספים להתקנה
אפשרויות התקנה נוספות זמינות במדריך להתקנת סוכן Bindplane.
הגדרה של סוכן Bindplane להטמעה של יומנים ושליחה שלהם אל Google SecOps
פותחים את קובץ התצורה של סוכן Bindplane בכלי לעריכת טקסט:
Linux:
sudo nano /opt/observiq-otel-collector/config.yamlWindows:
notepad "C:\Program Files\observIQ OpenTelemetry Collector\config.yaml"עורכים את הקובץ
config.yamlבאופן הבא:receivers: tcplog: listen_address: "0.0.0.0:5140" exporters: chronicle/akamai_eaa: protocol: https # Region of your instance, for example us, europe, asia-southeast1 location: <LOCATION> # Project number of the Google Cloud project linked to the instance project: '<PROJECT_NUMBER>' compression: gzip creds_file_path: '/path/to/ingestion-authentication-file.json' customer_id: '<CUSTOMER_ID>' endpoint: chronicle.googleapis.com log_type: 'AKAMAI_EAA' raw_log_field: body ingestion_labels: source: akamai_eaa service: pipelines: logs/akamai_eaa: receivers: - tcplog exporters: - chronicle/akamai_eaa
מחליפים את מה שכתוב בשדות הבאים:
-
/path/to/ingestion-authentication-file.json: הנתיב המלא לקובץ המפתח של חשבון השירות בפורמט JSON (אפשרות 1).- Linux:
/opt/observiq-otel-collector/ingestion-auth.json - Windows:
C:\Program Files\observIQ OpenTelemetry Collector\ingestion-auth.json
- Linux:
- מחליפים את
<LOCATION>באזור של מכונת Google SecOps (לדוגמה,us,europeאוasia-southeast1). הערך הזה יתווסף לתחילת השם של קובץ הייצואchronicle.googleapis.com. - מחליפים את
<PROJECT_NUMBER>במספר הפרויקט שמופיע בקטע IAM & Admin > Settings. -
<CUSTOMER_ID>: מספר הלקוח ב-Google SecOps. -
0.0.0.0:5140: כתובת ה-IP והיציאה שבהן Bindplane מאזין. מבצעים התאמות לפי הצורך בהתאם לסביבה.
מייצא API להטמעה מדור קודם
אם אתם משתמשים בקובץ האימות להטמעת נתונים מאפשרות 2, החליפו את הבלוק
exportersבקוד הבא. מגדירים אתcreds_file_pathלנתיב של קובץ האימות להטמעת נתונים. אם המכונה נמצאת מחוץ לארה"ב, מחליפים אתmalachiteingestion-pa.googleapis.comבנקודת הקצה האזורית (לדוגמה,europe-malachiteingestion-pa.googleapis.com).exporters: chronicle/akamai_eaa: compression: gzip creds_file_path: '/path/to/ingestion-authentication-file.json' customer_id: '<CUSTOMER_ID>' endpoint: malachiteingestion-pa.googleapis.com log_type: 'AKAMAI_EAA' raw_log_field: body ingestion_labels: source: akamai_eaa
מפעילים מחדש את הסוכן של Bindplane כדי להחיל את השינויים.
כדי להפעיל מחדש את הסוכן של Bindplane ב-Linux:
מריצים את הפקודה הבאה:
sudo systemctl restart observiq-otel-collectorמוודאים שהשירות פועל:
sudo systemctl status observiq-otel-collectorבודקים אם יש שגיאות ביומנים:
sudo journalctl -u observiq-otel-collector -f
כדי להפעיל מחדש את סוכן Bindplane ב-Windows:
בוחרים אחת מהאפשרויות האלה:
- שורת הפקודה או PowerShell כאדמין:
net stop observiq-otel-collector && net start observiq-otel-collector- מסוף השירותים:
- מקישים על
Win+R, מקלידיםservices.mscומקישים על Enter. - מאתרים את observIQ OpenTelemetry Collector.
- לוחצים לחיצה ימנית ובוחרים באפשרות הפעלה מחדש.
- מקישים על
מוודאים שהשירות פועל:
sc query observiq-otel-collectorבודקים אם יש שגיאות ביומנים:
type "C:\Program Files\observIQ OpenTelemetry Collector\log\collector.log"
יצירת פרטי כניסה ל-API של Akamai
ב-Akamai EAA משתמשים בשני סוגים של פרטי כניסה ל-API, בהתאם לסוג הפיד. יוצרים את פרטי הכניסה שתואמים לפידים שרוצים לאסוף.
יצירת פרטי כניסה ל-EAA Legacy API (לפידים של גישה ואדמין)
- נכנסים אל Akamai Control Center.
- בתפריט הניווט הראשי שמימין, לוחצים על Enterprise Center.
- עוברים אל הגדרות כלליות > הגדרות.
- לוחצים על הכרטיסייה מפתחות API.
- בפינה השמאלית העליונה, לוחצים על יצירת מפתח API חדש.
- מזינים שם ותיאור למפתח ה-API.
במסך האישור, מעתיקים את המפתח ואת הסוד.
יצירת פרטי כניסה ל-Akamai OPEN API (לעדכונים על תקינות המחבר, מלאי המכשירים ותקינות הספרייה)
- נכנסים אל Akamai Control Center.
- עוברים אל ניהול החשבון > זהות וגישה.
- לוחצים על הכרטיסייה משתמשי API.
- לוחצים על Create API Client (יצירת לקוח API).
- בקטע Select APIs, מחפשים את Enterprise Application Access ומגדירים את רמת הגישה ל-READ-WRITE.
- משלימים את שאר ההגדרות ולוחצים על Create API client (יצירת לקוח API).
לוחצים על Download כדי להוריד את פרטי הכניסה בפורמט
.edgerc, או לוחצים על Copy כדי להעתיק אותם לקובץ.edgercקיים.
הגדרת קובץ פרטי הכניסה של .edgerc
יוצרים את קובץ פרטי הכניסה של
.edgercבמערכת שבה יפעל ULS:touch ~/.edgercפותחים את הקובץ בכלי לעריכת טקסט:
nano ~/.edgercמוסיפים את פרטי הכניסה ל-Akamai API בפורמט הבא:
[default] ; EAA Legacy API credentials (for access and admin feeds) eaa_api_host = manage.akamai-access.com eaa_api_key = <EAA_API_KEY> eaa_api_secret = <EAA_API_SECRET> ; Akamai OPEN API credentials (for conhealth, devinv, dirhealth feeds) host = <OPEN_API_HOST> client_token = <CLIENT_TOKEN> client_secret = <CLIENT_SECRET> access_token = <ACCESS_TOKEN>מאבטחים את הקובץ של פרטי הכניסה:
chmod 600 ~/.edgerc
מחליפים את מה שכתוב בשדות הבאים:
-
<EAA_API_KEY>: מפתח ה-API הקודם של EAA (לדוגמה,XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX). -
<EAA_API_SECRET>: ה-API Secret מדור קודם של EAA. -
<OPEN_API_HOST>: שם המארח של Akamai OPEN API (לדוגמה,akaa-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx.luna.akamaiapis.net). -
<CLIENT_TOKEN>: טוקן לקוח ה-API של Akamai OPEN (לדוגמה,akab-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx). -
<CLIENT_SECRET>: סוד הלקוח של Akamai OPEN API.
<ACCESS_TOKEN>: טוקן הגישה של Akamai OPEN API (לדוגמה,akab-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx).
התקנה של Akamai Unified Log Streamer
הכלי Unified Log Streamer (ULS) שולף יומנים מ-Akamai EAA באמצעות ממשקי ה-API של Akamai ומזרים אותם לסוכן Bindplane באמצעות TCP. ULS היא אפליקציית Python שדורשת את Python 3.9 ואילך.
התקנה ב-Linux (Python)
משכפלים את מאגר ULS:
git clone https://github.com/akamai/uls.git cd ulsמתקינים את הדרישות של ULS Python:
pip3 install -r bin/requirements.txtמתקינים את יחסי התלות של EAA CLI:
git clone --depth 1 --single-branch https://github.com/akamai/cli-eaa.git ext/cli-eaa pip3 install -r ext/cli-eaa/requirements.txtמאמתים את ההתקנה:
python3 bin/uls.py --help
התקנת Docker
מורידים את קובץ האימג' הרשמי של ULS Docker:
docker pull akamai/uls:latest
הגדרת ULS להזרמת יומני EAA אל Bindplane
הפעלה של שורת הפקודה (בדיקה)
מריצים את ULS עם פלט TCP כדי להזרים יומנים לסוכן Bindplane:
python3 bin/uls.py --input eaa \ --feed access \ --output tcp \ --host <BINDPLANE_HOST> \ --port 5140 \ --edgerc ~/.edgerc \ --section default
מחליפים את מה שכתוב בשדות הבאים:
-
<BINDPLANE_HOST>: כתובת ה-IP או שם המארח של השרת שבו פועל סוכן Bindplane.
5140: היציאה שהוגדרה במקלטtcplogשל Bindplane.כדי להזרים כמה סוגי פידים, מריצים מופעים נפרדים של ULS:
# Access logs python3 bin/uls.py --input eaa --feed access --output tcp --host <BINDPLANE_HOST> --port 5140 --edgerc ~/.edgerc --section default # Admin audit logs python3 bin/uls.py --input eaa --feed admin --output tcp --host <BINDPLANE_HOST> --port 5140 --edgerc ~/.edgerc --section default # Connector health python3 bin/uls.py --input eaa --feed conhealth --output tcp --host <BINDPLANE_HOST> --port 5140 --edgerc ~/.edgerc --section default
שירות Systemd (ייצור)
בפריסות בסביבת ייצור, צריך להגדיר את ULS כשירות systemd.
יוצרים קובץ תצורה של ULS:
sudo mkdir -p /etc/uls sudo nano /etc/uls/eaa-access-tcp.confמוסיפים את ההגדרות הבאות:
ULS_INPUT=eaa ULS_FEED=access ULS_OUTPUT=tcp ULS_HOST=<BINDPLANE_HOST> ULS_PORT=5140 ULS_EDGERC=/root/.edgerc ULS_SECTION=defaultיוצרים קובץ שירות של systemd:
sudo nano /etc/systemd/system/uls-eaa-access.serviceמוסיפים את התוכן הבא:
[Unit] Description=Unified Log Streamer - EAA Access Logs to Bindplane After=network.target [Service] Type=simple EnvironmentFile=/etc/uls/eaa-access-tcp.conf ExecStart=/usr/bin/python3 /opt/uls/bin/uls.py --input ${ULS_INPUT} --feed ${ULS_FEED} --output ${ULS_OUTPUT} --host ${ULS_HOST} --port ${ULS_PORT} --edgerc ${ULS_EDGERC} --section ${ULS_SECTION} Restart=always RestartSec=10 User=root [Install] WantedBy=multi-user.targetמפעילים את השירות:
sudo systemctl daemon-reload sudo systemctl enable uls-eaa-access.service sudo systemctl start uls-eaa-access.serviceמוודאים שהשירות פועל:
sudo systemctl status uls-eaa-access.serviceצפייה ביומנים:
sudo journalctl -u uls-eaa-access.service -f
חוזרים על שלבים 1-7 לכל סוג פיד נוסף (admin, conhealth) על ידי יצירת קובצי תצורה ושירות נפרדים עם שמות שונים (לדוגמה, uls-eaa-admin.service, uls-eaa-conhealth.service).
פריסה של Docker Compose
יוצרים קובץ
docker-compose.yml:version: '3.8' services: uls-eaa-access: image: akamai/uls:latest container_name: uls-eaa-access restart: unless-stopped environment: - ULS_INPUT=eaa - ULS_FEED=access - ULS_OUTPUT=tcp - ULS_HOST=<BINDPLANE_HOST> - ULS_PORT=5140 volumes: - ~/.edgerc:/root/.edgerc:ro uls-eaa-admin: image: akamai/uls:latest container_name: uls-eaa-admin restart: unless-stopped environment: - ULS_INPUT=eaa - ULS_FEED=admin - ULS_OUTPUT=tcp - ULS_HOST=<BINDPLANE_HOST> - ULS_PORT=5140 volumes: - ~/.edgerc:/root/.edgerc:ro uls-eaa-conhealth: image: akamai/uls:latest container_name: uls-eaa-conhealth restart: unless-stopped environment: - ULS_INPUT=eaa - ULS_FEED=conhealth - ULS_OUTPUT=tcp - ULS_HOST=<BINDPLANE_HOST> - ULS_PORT=5140 volumes: - ~/.edgerc:/root/.edgerc:ro
מחליפים את <BINDPLANE_HOST> בכתובת ה-IP או בשם המארח של שרת הסוכן של Bindplane.
מפעילים את המאגרים:
docker compose up -dצפייה ביומנים:
docker compose logs -f
טבלת מיפוי UDM
| שדה ביומן | מיפוי UDM | היגיון |
|---|---|---|
app |
target.application |
הערך אחרי הנקודתיים בשדה app. |
apphost |
target.hostname |
ממופים ישירות. |
browser |
network.http.user_agent |
ממופים ישירות. |
bytes_in |
network.recieved_bytes |
ממופים ישירות. |
bytes_out |
network.sent_bytes |
ממופים ישירות. |
cc |
principal.location.country_or_region |
ממופים ישירות. |
client_id |
additional.fields.key: "Client Id", additional.fields.value.string_value: client_id |
ממופה באופן מותנה אם קיים client_id. |
clientip |
principal.ip |
ממופים ישירות. |
cloud_zone |
principal.cloud.availability_zone |
ממופים ישירות. |
connector_resp_time |
security_result.detection_fields.key: "Connector response time", security_result.detection_fields.value: connector_resp_time |
מיפוי מותנה אם הערך של connector_resp_time לא ריק או '-'. |
content_type |
additional.fields.key: "Content type", additional.fields.value.string_value: content_type |
ממופה באופן מותנה אם קיים content_type. |
datetime |
metadata.event_timestamp |
מנותח מהשדה datetime באמצעות פורמט RFC 3339. |
deny_reason |
security_result.summary |
מיפוי ישיר. |
device_type |
principal.platform, principal.platform_version |
ממופה ל-WINDOWS, ל-LINUX או ל-MAC על סמך התאמה לביטוי רגולרי. הערך הגולמי ממופה אל principal.platform_version. |
di |
metadata.ingestion_labels.key: "di", metadata.ingestion_labels.value: di |
ממופה ישירות כתווית הטמעה. |
error_code |
additional.fields.key: "קוד שגיאה", additional.fields.value.string_value: error_code |
ממופה באופן מותנה אם קיים error_code. |
event |
metadata.description |
מיפוי ישיר. |
geo_city |
principal.location.city |
ממופים ישירות. |
geo_country |
principal.location.country_or_region |
ממופים ישירות. |
geo_state |
principal.location.state |
ממופים ישירות. |
groups |
principal.user.group_identifiers |
ממופים ישירות. |
http_method |
network.http.method |
מיפוי ישיר. |
http_ver |
network.application_protocol, network.application_protocol_version |
מנותח באמצעות grok כדי לחלץ את הפרוטוקול והגרסה. |
idpinfo |
additional.fields.key: "IDP Info", additional.fields.value.string_value: idpinfo |
ממופה באופן מותנה אם קיים idpinfo. |
internal_host |
additional.fields.key: "מארח פנימי", additional.fields.value.string_value: internal_host |
מיפוי מותנה אם internal_host קיים. |
metadata.log_type |
metadata.log_type |
הערך מוטמע בקוד כ-AKAMAI_EAA. |
metadata.product_name |
metadata.product_name |
הערך מוטמע בקוד כ-AKAMAI_EAA. |
metadata.vendor_name |
metadata.vendor_name |
הערך מוטמע בקוד כ-AKAMAI_EAA. |
metadata.event_type |
metadata.event_type |
נקבע לפי לוגיקה: USER_UNCATEGORIZED אם uid קיים, NETWORK_HTTP אם גם principal.ip וגם target מוגדרים, או GENERIC_EVENT אחרת. |
origin_host |
additional.fields.key: "Origin host", additional.fields.value.string_value: origin_host |
מיפוי מותנה אם origin_host קיים. |
origin_resp_time |
security_result.detection_fields.key: "Origin response time", security_result.detection_fields.value: origin_resp_time |
מיפוי מותנה אם הערך של origin_resp_time לא ריק או '-'. |
os |
principal.platform |
ממופה ל-WINDOWS, ל-MAC או ל-LINUX על סמך התאמה לביטוי רגולרי. |
port |
target.port |
הערך אחרי הנקודתיים בשדה app. |
ral |
metadata.description |
ערכים משורשרים של המערך ral, מופרדים בפסיקים. |
referer |
network.http.referral_url |
מיפוי ישיר. |
resource |
principal.resource.attribute.labels.key: "Resource", principal.resource.attribute.labels.value: resource |
ממופה באופן מותנה אם קיים resource. |
resource_type |
principal.resource.attribute.labels.key: "Resource Type", principal.resource.attribute.labels.value: resource_type |
מיפוי מותנה אם resource_type קיים. |
rscd |
metadata.ingestion_labels.key: "rscd", metadata.ingestion_labels.value: rscd |
ממופה ישירות כתווית הטמעה. |
session_id |
network.session_id |
ממופים ישירות. |
session_info |
additional.fields.key: "Session info", additional.fields.value.string_value: session_info |
מיפוי מותנה אם session_info קיים. |
state |
principal.location.state |
מיפוי ישיר. |
status_code |
network.http.response_code |
מיפוי ישיר. |
total_resp_time |
security_result.detection_fields.key: "זמן תגובה כולל", security_result.detection_fields.value: total_resp_time |
מיפוי מותנה אם total_resp_time לא ריק או לא מכיל "-". |
ts |
metadata.event_timestamp |
מנותח מהשדה ts כאלפיות השנייה או כשניות של UNIX אם הוא קיים, אחרת מהשדה datetime. |
uid |
principal.user.userid |
ממופים ישירות. |
uip |
principal.ip |
ממופים ישירות. |
url_path |
target.url |
מיפוי ישיר. |
user_agent |
network.http.user_agent, network.http.parsed_user_agent |
ממופים ומנותחים ישירות לשדה מובנה parsed_user_agent. |
username |
principal.user.email_addresses או principal.user.userid |
ממופה אל email_addresses אם זה נראה כמו כתובת אימייל, אחרת אל userid. |
יומן שינויים
צפייה ביומן השינויים של המנתח הזה
הבעיה עדיין לא נפתרה? קבלת תשובות מחברי הקהילה וממומחי Google SecOps.