Raccogliere i log di Akamai EAA (Enterprise Application Access)
Questo documento spiega come importare i log di Akamai Enterprise Application Access (EAA) in Google Security Operations utilizzando Unified Log Streamer (ULS) e Bindplane di Akamai. Akamai EAA produce dati operativi sotto forma di log di accesso, audit log amministrativi, dettagli di autenticazione e metriche di integrità del connettore. Il parser estrae i campi dai log JSON, esegue trasformazioni dei dati come conversioni di stringhe ed estrazione di indirizzi IP e mappa questi campi all'UDM, gestendo vari tipi di eventi come NETWORK_HTTP e USER_UNCATEGORIZED in base alla presenza di campi specifici. Inoltre, aggiunge metadati come i nomi del fornitore e del prodotto all'evento UDM.
Prima di iniziare
Assicurati di soddisfare i seguenti prerequisiti:
- Un'istanza Google SecOps
- Un host Windows 2016 o versioni successive o Linux con
systemdper eseguire l'agente Bindplane - Linux, macOS o ambiente containerizzato (Docker/Kubernetes) per eseguire Unified Log Streamer
- Se l'agente viene eseguito dietro un proxy, assicurati che le porte del firewall siano aperte in base ai requisiti dell'agente Bindplane.
- Tenant Akamai EAA con accesso amministrativo
- Credenziali API Akamai (autenticazione EdgeGrid):
- Token di accesso
- Token client
- Client secret
- Nome host di base dell'API (ad esempio,
akab-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx.luna.akamaiapis.net)
Recuperare il file di autenticazione importazione di Google SecOps
- Accedi alla console Google SecOps.
- Vai a Impostazioni SIEM > Agenti di raccolta.
- Scarica il file di autenticazione importazione. Salva il file in modo sicuro sul sistema in cui verrà installato Bindplane.
Recuperare l'ID cliente Google SecOps
- Accedi alla console Google SecOps.
- Vai a Impostazioni SIEM > Profilo.
- Copia e salva l'ID cliente dalla sezione Dettagli dell'organizzazione.
Installa l'agente Bindplane
Installa l'agente Bindplane sul sistema operativo Windows o Linux seguendo le istruzioni riportate di seguito.
Installazione di Windows
- Apri il prompt dei comandi o PowerShell come amministratore.
Esegui questo comando:
msiexec /i "https://github.com/observIQ/bindplane-agent/releases/latest/download/observiq-otel-collector.msi" /quiet
Installazione di Linux
- Apri un terminale con privilegi root o sudo.
Esegui questo comando:
sudo sh -c "$(curl -fsSlL https://github.com/observiq/bindplane-agent/releases/latest/download/install_unix.sh)" install_unix.sh
Risorse aggiuntive per l'installazione
- Per ulteriori opzioni di installazione, consulta questa guida all'installazione.
Configura l'agente Bindplane per importare Syslog e inviarlo a Google SecOps
Accedi al file di configurazione:
- Individua il file
config.yaml. In genere si trova nella directory/etc/bindplane-agent/su Linux o nella directory di installazione su Windows. - Apri il file utilizzando un editor di testo (ad esempio
nano,vio Blocco note).
- Individua il file
Modifica il file
config.yamlcome segue:receivers: tcplog: listen_address: "0.0.0.0:5140" exporters: chronicle/chronicle_w_labels: 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 service: pipelines: logs/akamai_eaa: receivers: - tcplog exporters: - chronicle/chronicle_w_labels- Sostituisci quanto segue:
- Sostituisci
<CUSTOMER_ID>con l'ID cliente effettivo. - Aggiorna
/path/to/ingestion-authentication-file.jsonal percorso in cui è stato salvato il file di autenticazione nella sezione Recupera il file di autenticazione per l'importazione di Google SecOps. 0.0.0.0:5140: l'indirizzo IP e la porta su cui Bindplane deve rimanere in ascolto. Modifica in base alle esigenze del tuo ambiente.
- Sostituisci
- Sostituisci quanto segue:
Riavvia l'agente Bindplane per applicare le modifiche
Per riavviare l'agente Bindplane in Linux, esegui questo comando:
sudo systemctl restart bindplane-agentPer riavviare l'agente Bindplane in Windows, puoi utilizzare la console Servizi o inserire il seguente comando:
net stop BindPlaneAgent && net start BindPlaneAgent
Installa Akamai Unified Log Streamer
Unified Log Streamer (ULS) estrae i log da Akamai EAA tramite l'API Enterprise Application Access e li trasmette in streaming a Bindplane utilizzando TCP o UDP.
Installazione di Linux
Scarica l'ultima release di ULS:
curl -LO https://github.com/akamai/uls/releases/latest/download/uls-linux-amd64Rendi eseguibile il file binario:
chmod +x uls-linux-amd64Spostalo in una posizione standard:
sudo mv uls-linux-amd64 /usr/local/bin/uls
Installazione di macOS
Scarica l'ultima release di ULS:
curl -LO https://github.com/akamai/uls/releases/latest/download/uls-darwin-amd64Rendi eseguibile il file binario:
chmod +x uls-darwin-amd64Spostalo in una posizione standard:
sudo mv uls-darwin-amd64 /usr/local/bin/uls
Installazione di Docker
Esegui il pull dell'immagine Docker ULS ufficiale:
docker pull akamai/uls:latest
Configurare le credenziali Akamai EdgeGrid
Crea il file delle credenziali EdgeGrid:
mkdir -p ~/.edgerc nano ~/.edgercAggiungi le credenziali API di Akamai nel seguente formato:
[default] client_secret = your-client-secret host = akab-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx.luna.akamaiapis.net access_token = your-access-token client_token = your-client-tokenProteggi il file delle credenziali:
chmod 600 ~/.edgerc
Sostituisci quanto segue:
your-client-secret: il tuo client secret Akamai.your-access-token: il tuo token di accesso Akamai.your-client-token: il tuo token client Akamai.akab-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx.luna.akamaiapis.net: il nome host di base dell'API Akamai.
Configurare ULS per lo streaming dei log EAA in BindPlane
Esecuzione da riga di comando (test)
Esegui ULS con output TCP per trasmettere in streaming i log all'agente Bindplane:
uls --input eaa \
--feed access \
--output tcp \
--host <BINDPLANE_HOST> \
--port 5140 \
--edgerc ~/.edgerc \
--section default
- Sostituisci quanto segue:
<BINDPLANE_HOST>: L'indirizzo IP o il nome host del server che esegue Bindplane5140: la porta configurata nel ricevitoretcplogdi Bindplane
Per trasmettere in streaming più tipi di feed, esegui istanze ULS separate:
```bash
# Access logs
uls --input eaa --feed access --output tcp --host <BINDPLANE_HOST> --port 5140 --edgerc ~/.edgerc --section default
# Admin audit logs
uls --input eaa --feed admin --output tcp --host <BINDPLANE_HOST> --port 5140 --edgerc ~/.edgerc --section default
# Connector health
uls --input eaa --feed conhealth --output tcp --host <BINDPLANE_HOST> --port 5140 --edgerc ~/.edgerc --section default
```
Servizio Systemd (produzione)
Per le implementazioni di produzione, configura ULS come servizio systemd:
Crea un file di configurazione ULS:
sudo mkdir -p /etc/uls sudo nano /etc/uls/eaa-access-tcp.confAggiungi la seguente configurazione:
ULS_INPUT=eaa ULS_FEED=access ULS_OUTPUT=tcp ULS_HOST=<BINDPLANE_HOST> ULS_PORT=5140 ULS_EDGERC=/root/.edgerc ULS_SECTION=defaultCrea un file di servizio systemd:
sudo nano /etc/systemd/system/uls-eaa-access.serviceAggiungi i seguenti contenuti:
[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/local/bin/uls --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.targetAttiva e avvia il servizio:
sudo systemctl daemon-reload sudo systemctl enable uls-eaa-access.service sudo systemctl start uls-eaa-access.serviceVerifica che il servizio sia in esecuzione:
sudo systemctl status uls-eaa-access.serviceVisualizza i log:
sudo journalctl -u uls-eaa-access.service -f
Ripeti i passaggi da 1 a 7 per ogni tipo di feed aggiuntivo (amministratore, conhealth) creando file di configurazione e di servizio separati con nomi diversi (ad esempio, uls-eaa-admin.service, uls-eaa-conhealth.service).
Deployment Docker
Crea un file Docker Compose:
nano docker-compose.ymlAggiungi la seguente configurazione:
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 command: > --input eaa --feed access --output tcp --host "$${ULS_HOST}" --port "$${ULS_PORT}" --edgerc /root/.edgerc --section default 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 command: > --input eaa --feed admin --output tcp --host "$${ULS_HOST}" --port "$${ULS_PORT}" --edgerc /root/.edgerc --section default 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 command: > --input eaa --feed conhealth --output tcp --host "$${ULS_HOST}" --port "$${ULS_PORT}" --edgerc /root/.edgerc --section default- Sostituisci
<BINDPLANE_HOST>con l'indirizzo IP o il nome host del server Bindplane.
- Sostituisci
Avvia i container:
docker-compose up -dVisualizza i log:
docker-compose logs -f
Tabella di mappatura UDM
| Campo log | Mappatura UDM | Logic |
|---|---|---|
app |
target.application |
Il valore dopo i due punti nel campo app. |
apphost |
target.hostname |
Mappato direttamente. |
browser |
network.http.user_agent |
Mappato direttamente. |
bytes_in |
network.received_bytes |
Mappato direttamente. |
bytes_out |
network.sent_bytes |
Mappato direttamente. |
cc |
principal.location.country_or_region |
Mappato direttamente. |
client_id |
additional.fields.key: "Client Id", additional.fields.value.string_value: client_id |
Mappato in modo condizionale se è presente client_id. |
clientip |
principal.ip |
Mappato direttamente. |
cloud_zone |
principal.cloud.availability_zone |
Mappato direttamente. |
connector_resp_time |
security_result.detection_fields.key: "Tempo di risposta del connettore", security_result.detection_fields.value: connector_resp_time |
Mappato in modo condizionale se connector_resp_time non è vuoto o "-". |
content_type |
additional.fields.key: "Tipo di contenuti", additional.fields.value.string_value: content_type |
Mappato in modo condizionale se è presente content_type. |
datetime |
metadata.event_timestamp |
Analizzato dal campo datetime utilizzando il formato RFC3339. |
deny_reason |
security_result.summary |
Mappato direttamente. |
device_type |
principal.platform, principal.platform_version |
Mappato a WINDOWS, LINUX o MAC in base alla corrispondenza con l'espressione regolare. Il valore non elaborato è mappato a principal.platform_version. |
di |
metadata.ingestion_labels.key: "di", metadata.ingestion_labels.value: di |
Mappato direttamente come etichetta di importazione. |
error_code |
additional.fields.key: "Error code", additional.fields.value.string_value: error_code |
Mappato in modo condizionale se è presente error_code. |
event |
metadata.description |
Mappato direttamente. |
geo_city |
principal.location.city |
Mappato direttamente. |
geo_country |
principal.location.country_or_region |
Mappato direttamente. |
geo_state |
principal.location.state |
Mappato direttamente. |
groups |
principal.user.group_identifiers |
Mappato direttamente. |
http_method |
network.http.method |
Mappato direttamente. |
http_ver |
network.application_protocol, network.application_protocol_version |
Analizzato utilizzando grok per estrarre il protocollo e la versione. |
idpinfo |
additional.fields.key: "IDP Info", additional.fields.value.string_value: idpinfo |
Mappato in modo condizionale se è presente idpinfo. |
internal_host |
additional.fields.key: "Internal host", additional.fields.value.string_value: internal_host |
Mappato in modo condizionale se è presente internal_host. |
metadata.log_type |
metadata.log_type |
Codificato in modo permanente su "AKAMAI_EAA". |
metadata.product_name |
metadata.product_name |
Codificato in modo permanente su "AKAMAI_EAA". |
metadata.vendor_name |
metadata.vendor_name |
Codificato in modo permanente su "AKAMAI_EAA". |
metadata.event_type |
metadata.event_type |
Determinato dalla logica: USER_UNCATEGORIZED se è presente uid, NETWORK_HTTP se sono impostati sia principal.ip che target o GENERIC_EVENT altrimenti. |
origin_host |
additional.fields.key: "Origin host", additional.fields.value.string_value: origin_host |
Mappato in modo condizionale se è presente origin_host. |
origin_resp_time |
security_result.detection_fields.key: "Tempo di risposta dell'origine", security_result.detection_fields.value: origin_resp_time |
Mappato in modo condizionale se origin_resp_time non è vuoto o "-". |
os |
principal.platform |
Mappato a WINDOWS, MAC o LINUX in base alla corrispondenza con l'espressione regolare. |
port |
target.port |
Il valore dopo i due punti nel campo app. |
ral |
metadata.description |
Valori concatenati dell'array ral, separati da virgole. |
referer |
network.http.referral_url |
Mappato direttamente. |
resource |
principal.resource.attribute.labels.key: "Resource", principal.resource.attribute.labels.value: resource |
Mappato in modo condizionale se è presente resource. |
resource_type |
principal.resource.attribute.labels.key: "Tipo di risorsa", principal.resource.attribute.labels.value: resource_type |
Mappato in modo condizionale se è presente resource_type. |
rscd |
metadata.ingestion_labels.key: "rscd", metadata.ingestion_labels.value: rscd |
Mappato direttamente come etichetta di importazione. |
session_id |
network.session_id |
Mappato direttamente. |
session_info |
additional.fields.key: "Session info", additional.fields.value.string_value: session_info |
Mappato in modo condizionale se è presente session_info. |
state |
principal.location.state |
Mappato direttamente. |
status_code |
network.http.response_code |
Mappato direttamente. |
total_resp_time |
security_result.detection_fields.key: "Tempo di risposta totale", security_result.detection_fields.value: total_resp_time |
Mappato in modo condizionale se total_resp_time non è vuoto o "-". |
ts |
metadata.event_timestamp |
Analizzato dal campo ts come millisecondi o secondi UNIX, se presente, altrimenti dal campo datetime. |
uid |
principal.user.userid |
Mappato direttamente. |
uip |
principal.ip |
Mappato direttamente. |
url_path |
target.url |
Mappato direttamente. |
user_agent |
network.http.user_agent, network.http.parsed_user_agent |
Mappato e analizzato direttamente in un campo parsed_user_agent strutturato. |
username |
principal.user.email_addresses o principal.user.userid |
Mappato a email_addresses se sembra un'email, altrimenti a userid. |
Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.