Raccogliere i log di Akamai Enterprise Application Access
Versione parser: 3.0
Questo documento spiega come importare i log di Akamai Enterprise Application Access (EAA) in Google Security Operations utilizzando Akamai Unified Log Streamer (ULS) e Bindplane. Akamai EAA è una soluzione di accesso alla rete Zero Trust che fornisce un accesso sicuro e sensibile all'identità alle applicazioni aziendali senza una VPN tradizionale. EAA produce dati operativi sotto forma di log di accesso, audit log amministrativi, metriche di integrità del connettore, inventario dei dispositivi e informazioni sull'integrità della directory. 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, tra cui NETWORK_HTTP e USER_UNCATEGORIZED, in base alla presenza di campi specifici.
Prima di iniziare
Assicurati di soddisfare i seguenti prerequisiti:
- Un'istanza Google SecOps.
- Un host Windows Server 2016 o versioni successive o Linux con
systemdper eseguire l'agente Bindplane. - Host Linux con Python 3.9 o versioni successive o un ambiente containerizzato (Docker o Kubernetes) per eseguire Unified Log Streamer.
- Se l'esecuzione avviene 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:
- Per i feed di controllo dell'accesso e dell'amministrazione: chiave e segreto API legacy EAA (creati in Enterprise Center).
- Per i feed sullo stato del connettore, l'inventario dei dispositivi e lo stato della directory: credenziali dell'API Akamai OPEN (autenticazione EdgeGrid) con accesso in lettura/scrittura all'API Enterprise Application Access.
Ottieni le credenziali di Google SecOps per l'agente Bindplane
Per autenticare l'agente Bindplane in Google SecOps, scegli uno dei seguenti metodi:
- Nuovi deployment: utilizza l'API Chronicle (opzione 1).
- Deployment legacy: continua a utilizzare il file di autenticazione dell'acquisizione (Opzione 2) fino alla dismissione dell'API Ingestion il 20 luglio 2027.
Opzione 1: crea un account di servizio per l'API Chronicle (consigliata)
- Accedi alla consoleGoogle Cloud e seleziona il progetto Google Cloud collegato alla tua istanza Google SecOps.
- Vai a IAM e amministrazione > Service account.
- Fai clic su Crea service account.
- Fornisci i seguenti dettagli di configurazione:
- Nome service account: inserisci un nome per l'account (ad esempio
bindplane-ingest). - Descrizione service account: inserisci una descrizione (ad esempio
Bindplane agent log ingestion).
- Nome service account: inserisci un nome per l'account (ad esempio
- Fai clic su Crea e continua.
- Nella sezione Concedi a questo account di servizio l'accesso al progetto, fai clic su Seleziona un ruolo e seleziona Editor Chronicle.
- Fai clic su Continua e poi su Fine.
- Fai clic sul account di servizio che hai creato, quindi vai alla scheda Chiavi.
- Fai clic su Aggiungi chiave > Crea nuova chiave.
- Seleziona JSON e fai clic su Crea. Il file della chiave viene scaricato sul tuo computer.
- Salva il file della chiave come
ingestion-auth.jsonnella directory del raccoglitore Bindplane (/opt/observiq-otel-collector/ingestion-auth.jsonsu Linux oC:\Program Files\observIQ OpenTelemetry Collector\ingestion-auth.jsonsu Windows) oppure aggiornacreds_file_pathinconfig.yamlin modo che corrisponda al percorso in cui lo salvi. - Vai a IAM e amministrazione > Impostazioni e copia il Numero progetto. Ti servirà per la configurazione dell'esportatore.
Opzione 2: scarica il file di autenticazione dell'acquisizione (legacy)
- Accedi alla console Google SecOps.
- Vai a Impostazioni SIEM > Agenti di raccolta.
- Scarica il file di autenticazione dell'acquisizione.
- Salva il file in modo sicuro sul sistema in cui verrà installato l'agente Bindplane.
Ottieni 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 finestre
- 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 la guida all'installazione dell'agente Bindplane.
Configura l'agente Bindplane per importare i log e inviarli a Google SecOps
Apri il file di configurazione dell'agente Bindplane in un editor di testo:
Linux:
sudo nano /opt/observiq-otel-collector/config.yamlWindows:
notepad "C:\Program Files\observIQ OpenTelemetry Collector\config.yaml"Modifica il file
config.yamlcome segue: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
Sostituisci quanto segue:
/path/to/ingestion-authentication-file.json: il percorso completo del file della chiave JSON del account di servizio (opzione 1).- Linux:
/opt/observiq-otel-collector/ingestion-auth.json - Windows:
C:\Program Files\observIQ OpenTelemetry Collector\ingestion-auth.json
- Linux:
- Sostituisci
<LOCATION>con la regione della tua istanza Google SecOps (ad esempious,europeoasia-southeast1). L'esportatore anteponechronicle.googleapis.coma questo valore. - Sostituisci
<PROJECT_NUMBER>con il numero di progetto in IAM e amministrazione > Impostazioni. <CUSTOMER_ID>: l'ID cliente 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.
Esportatore API di importazione legacy
Se utilizzi il file di autenticazione dell'acquisizione dell'Opzione 2, sostituisci il blocco
exporterscon il seguente. Impostacreds_file_pathsul percorso del file di autenticazione dell'acquisizione e, se l'istanza si trova al di fuori degli Stati Uniti, sostituiscimalachiteingestion-pa.googleapis.comcon il tuo endpoint regionale (ad esempio,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
Riavvia l'agente Bindplane per applicare le modifiche
Per riavviare l'agente Bindplane in Linux:
Esegui questo comando:
sudo systemctl restart observiq-otel-collectorVerifica che il servizio sia in esecuzione:
sudo systemctl status observiq-otel-collectorControlla i log per verificare la presenza di errori:
sudo journalctl -u observiq-otel-collector -f
Per riavviare l'agente Bindplane in Windows:
Scegli una delle seguenti opzioni:
- Prompt dei comandi o PowerShell come amministratore:
net stop observiq-otel-collector && net start observiq-otel-collector- Console dei servizi:
- Premi
Win+R, digitaservices.msce premi Invio. - Individua observIQ OpenTelemetry Collector.
- Fai clic con il tasto destro del mouse e seleziona Riavvia.
- Premi
Verifica che il servizio sia in esecuzione:
sc query observiq-otel-collectorControlla i log per individuare eventuali errori:
type "C:\Program Files\observIQ OpenTelemetry Collector\log\collector.log"
Crea credenziali API Akamai
Akamai EAA utilizza due tipi di credenziali API a seconda del tipo di feed. Crea le credenziali corrispondenti ai feed che vuoi raccogliere.
Crea credenziali API legacy EAA (per i feed di accesso e amministrativi)
- Accedi ad Akamai Control Center.
- Seleziona Enterprise Center dal menu di navigazione principale a sinistra.
- Vai a Impostazioni generali > Impostazioni.
- Seleziona la scheda Chiavi API.
- Fai clic su Genera nuova chiave API nell'angolo in alto a destra.
- Inserisci un nome e una descrizione per la chiave API.
Nella schermata di conferma, copia la chiave e il secret.
Crea le credenziali API Akamai OPEN (per i feed di integrità del connettore, inventario dei dispositivi e integrità della directory)
- Accedi ad Akamai Control Center.
- Vai ad Amministrazione account > Identità e accesso.
- Seleziona la scheda Utenti API.
- Fai clic su Crea client API.
- Nella sezione Seleziona API, cerca Enterprise Application Access e imposta il livello di accesso su LETTURA-SCRITTURA.
- Completa le restanti impostazioni e fai clic su Crea client API.
Fai clic su Scarica per scaricare le credenziali in formato
.edgercoppure fai clic su Copia per copiarle in un file.edgercesistente.
Configurare il file delle credenziali .edgerc
Crea il file delle credenziali
.edgercsul sistema in cui verrà eseguito ULS:touch ~/.edgercApri il file in un editor di testo:
nano ~/.edgercAggiungi le credenziali API Akamai nel seguente formato:
[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>Proteggi il file delle credenziali:
chmod 600 ~/.edgerc
Sostituisci quanto segue:
<EAA_API_KEY>: la chiave API legacy di EAA (ad esempio,XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX).<EAA_API_SECRET>: l'API secret legacy di EAA.<OPEN_API_HOST>: il nome host dell'API Akamai OPEN (ad esempio,akaa-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx.luna.akamaiapis.net).<CLIENT_TOKEN>: il tuo token client API Akamai OPEN (ad esempio,akab-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx).<CLIENT_SECRET>: il client secret dell'API OPEN di Akamai.<ACCESS_TOKEN>: il tuo token di accesso all'API Akamai OPEN (ad esempio,akab-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx).
Installa Akamai Unified Log Streamer
Unified Log Streamer (ULS) estrae i log da Akamai EAA tramite le API Akamai e li trasmette in streaming all'agente Bindplane utilizzando TCP. ULS è un'applicazione Python che richiede Python 3.9 o versioni successive.
Installazione su Linux (Python)
Clona il repository ULS:
git clone https://github.com/akamai/uls.git cd ulsInstalla i requisiti Python di ULS:
pip3 install -r bin/requirements.txtInstalla la dipendenza 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.txtVerifica l'installazione:
python3 bin/uls.py --help
Installazione di Docker
Esegui il pull dell'immagine Docker ULS ufficiale:
docker pull akamai/uls:latest
Configura ULS per lo streaming dei log EAA su Bindplane
Esecuzione da riga di comando (test)
Esegui ULS con output TCP per trasmettere i log in streaming all'agente Bindplane:
python3 bin/uls.py --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 l'agente Bindplane.5140: la porta configurata nel ricevitore Bindplanetcplog.Per trasmettere in streaming più tipi di feed, esegui istanze ULS separate:
# 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
Servizio Systemd (produzione)
Per i deployment 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/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.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 (admin, conhealth) creando file di configurazione e di servizio separati con nomi diversi (ad esempio uls-eaa-admin.service, uls-eaa-conhealth.service).
Deployment di Docker Compose
Crea un file
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
Sostituisci <BINDPLANE_HOST> con l'indirizzo IP o il nome host del server dell'agente Bindplane.
Avvia i container:
docker compose up -dVisualizza i log:
docker compose logs -f
Tabella di mappatura UDM
| Campo log | mappatura UDM | Logica |
|---|---|---|
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.recieved_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 content_type è presente. |
datetime |
metadata.event_timestamp |
Analizzato dal campo datetime utilizzando il formato RFC 3339. |
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 error_code è presente. |
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 |
Impostato come hardcoded su "AKAMAI_EAA". |
metadata.product_name |
metadata.product_name |
Impostato come hardcoded 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 in caso contrario. |
origin_host |
additional.fields.key: "Host di origine", 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: "Informazioni sulla sessione", additional.fields.value.string_value: session_info |
Mappato in modo condizionale se session_info è presente. |
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. |
Log delle modifiche
Visualizza il log delle modifiche per questo parser
Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.