Recolha registos da Akamai EAA (Enterprise Application Access)
Este documento explica como carregar registos do Akamai Enterprise Application Access (EAA) para o Google Security Operations através do Unified Log Streamer (ULS) e do Bindplane da Akamai. O Akamai EAA produz dados operacionais sob a forma de registos de acesso, registos de auditoria do administrador, detalhes de autenticação e métricas de estado do conector. O analisador sintático extrai campos dos registos JSON, realiza transformações de dados, como conversões de strings e extração de endereços IP, e mapeia estes campos para o UDM, processando vários tipos de eventos, como NETWORK_HTTP e USER_UNCATEGORIZED, com base na presença de campos específicos. Também adiciona metadados, como os nomes dos fornecedores e dos produtos, ao evento da UDM.
Antes de começar
Certifique-se de que cumpre os seguintes pré-requisitos:
- Uma instância do Google SecOps
- Um anfitrião Windows 2016 ou posterior, ou Linux com
systemdpara executar o agente Bindplane - Linux, macOS ou ambiente em contentores (Docker/Kubernetes) para executar o Unified Log Streamer
- Se estiver a ser executado através de um proxy, certifique-se de que as portas da firewall estão abertas de acordo com os requisitos do agente Bindplane
- Inquilino do EAA da Akamai com acesso administrativo
- Credenciais da API Akamai (autenticação EdgeGrid):
- Token de acesso
- Símbolo de cliente
- Segredo do cliente
- Nome do anfitrião base da API (por exemplo,
akab-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx.luna.akamaiapis.net)
Obtenha o ficheiro de autenticação de carregamento do Google SecOps
- Inicie sessão na consola Google SecOps.
- Aceda a Definições do SIEM > Agentes de recolha.
- Transfira o ficheiro de autenticação de carregamento. Guarde o ficheiro de forma segura no sistema onde o Bindplane vai ser instalado.
Obtenha o ID de cliente do Google SecOps
- Inicie sessão na consola Google SecOps.
- Aceda a Definições do SIEM > Perfil.
- Copie e guarde o ID do cliente da secção Detalhes da organização.
Instale o agente do Bindplane
Instale o agente do Bindplane no seu sistema operativo Windows ou Linux de acordo com as seguintes instruções.
Instalação de janelas
- Abra a Linha de comandos ou o PowerShell como administrador.
Execute o seguinte comando:
msiexec /i "https://github.com/observIQ/bindplane-agent/releases/latest/download/observiq-otel-collector.msi" /quiet
Instalação do Linux
- Abra um terminal com privilégios de raiz ou sudo.
Execute o seguinte comando:
sudo sh -c "$(curl -fsSlL https://github.com/observiq/bindplane-agent/releases/latest/download/install_unix.sh)" install_unix.sh
Recursos de instalação adicionais
- Para ver opções de instalação adicionais, consulte este guia de instalação.
Configure o agente Bindplane para carregar o Syslog e enviá-lo para o Google SecOps
Aceda ao ficheiro de configuração:
- Localize o ficheiro
config.yaml. Normalmente, encontra-se no diretório/etc/bindplane-agent/no Linux ou no diretório de instalação no Windows. - Abra o ficheiro com um editor de texto (por exemplo,
nano,viou Bloco de notas).
- Localize o ficheiro
Edite o ficheiro
config.yamlda seguinte forma: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- Substitua o seguinte:
- Substitua
<CUSTOMER_ID>pelo ID de cliente real. - Atualize
/path/to/ingestion-authentication-file.jsonpara o caminho onde o ficheiro de autenticação foi guardado na secção Obtenha o ficheiro de autenticação de carregamento do Google SecOps. 0.0.0.0:5140: o endereço IP e a porta para o Bindplane ouvir. Ajuste conforme necessário para o seu ambiente.
- Substitua
- Substitua o seguinte:
Reinicie o agente do Bindplane para aplicar as alterações
Para reiniciar o agente do Bindplane no Linux, execute o seguinte comando:
sudo systemctl restart bindplane-agentPara reiniciar o agente Bindplane no Windows, pode usar a consola Serviços ou introduzir o seguinte comando:
net stop BindPlaneAgent && net start BindPlaneAgent
Instale o Akamai Unified Log Streamer
O Unified Log Streamer (ULS) extrai registos do Akamai EAA através da API Enterprise Application Access e transmite-os para o Bindplane através de TCP ou UDP.
Instalação do Linux
Transfira a versão mais recente do ULS:
curl -LO https://github.com/akamai/uls/releases/latest/download/uls-linux-amd64Torne o ficheiro binário executável:
chmod +x uls-linux-amd64Movê-lo para uma localização padrão:
sudo mv uls-linux-amd64 /usr/local/bin/uls
Instalação no macOS
Transfira a versão mais recente do ULS:
curl -LO https://github.com/akamai/uls/releases/latest/download/uls-darwin-amd64Torne o ficheiro binário executável:
chmod +x uls-darwin-amd64Movê-lo para uma localização padrão:
sudo mv uls-darwin-amd64 /usr/local/bin/uls
Instalação do Docker
Extraia a imagem oficial do Docker do ULS:
docker pull akamai/uls:latest
Configure as credenciais do Akamai EdgeGrid
Crie o ficheiro de credenciais do EdgeGrid:
mkdir -p ~/.edgerc nano ~/.edgercAdicione as suas credenciais da API Akamai no seguinte formato:
[default] client_secret = your-client-secret host = akab-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx.luna.akamaiapis.net access_token = your-access-token client_token = your-client-tokenProteja o ficheiro de credenciais:
chmod 600 ~/.edgerc
Substitua o seguinte:
your-client-secret: o segredo do cliente da Akamai.your-access-token: o seu token de acesso da Akamai.your-client-token: o seu token de cliente da Akamai.akab-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx.luna.akamaiapis.net: o nome do anfitrião base da API Akamai.
Configure o ULS para transmitir registos de EAA para o BindPlane
Execução de linhas de comandos (testes)
Execute o ULS com saída TCP para transmitir registos para o agente Bindplane:
uls --input eaa \
--feed access \
--output tcp \
--host <BINDPLANE_HOST> \
--port 5140 \
--edgerc ~/.edgerc \
--section default
- Substitua o seguinte:
<BINDPLANE_HOST>: o endereço IP ou o nome de anfitrião do servidor que executa o Bindplane5140: a porta configurada no recetortcplogdo Bindplane
Para fazer streaming de vários tipos de feeds, execute instâncias ULS separadas:
```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
```
Serviço systemd (produção)
Para implementações de produção, configure o ULS como um serviço systemd:
Crie um ficheiro de configuração ULS:
sudo mkdir -p /etc/uls sudo nano /etc/uls/eaa-access-tcp.confAdicione a seguinte configuração:
ULS_INPUT=eaa ULS_FEED=access ULS_OUTPUT=tcp ULS_HOST=<BINDPLANE_HOST> ULS_PORT=5140 ULS_EDGERC=/root/.edgerc ULS_SECTION=defaultCrie um ficheiro de serviço systemd:
sudo nano /etc/systemd/system/uls-eaa-access.serviceAdicione o seguinte conteúdo:
[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.targetAtive e inicie o serviço:
sudo systemctl daemon-reload sudo systemctl enable uls-eaa-access.service sudo systemctl start uls-eaa-access.serviceVerifique se o serviço está em execução:
sudo systemctl status uls-eaa-access.serviceVer registos:
sudo journalctl -u uls-eaa-access.service -f
Repita os passos 1 a 7 para cada tipo de feed adicional (admin, conhealth) criando ficheiros de configuração e de serviço separados com nomes diferentes (por exemplo, uls-eaa-admin.service, uls-eaa-conhealth.service).
Implementação do Docker
Crie um ficheiro Docker Compose:
nano docker-compose.ymlAdicione a seguinte configuração:
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- Substitua
<BINDPLANE_HOST>pelo endereço IP ou pelo nome de anfitrião do seu servidor Bindplane.
- Substitua
Inicie os contentores:
docker-compose up -dVer registos:
docker-compose logs -f
Tabela de mapeamento da UDM
| Campo de registo | Mapeamento do UDM | Lógica |
|---|---|---|
app |
target.application |
O valor após os dois pontos no campo app. |
apphost |
target.hostname |
Mapeado diretamente. |
browser |
network.http.user_agent |
Mapeado diretamente. |
bytes_in |
network.received_bytes |
Mapeado diretamente. |
bytes_out |
network.sent_bytes |
Mapeado diretamente. |
cc |
principal.location.country_or_region |
Mapeado diretamente. |
client_id |
additional.fields.key: "Client Id", additional.fields.value.string_value: client_id |
Mapeado condicionalmente se client_id estiver presente. |
clientip |
principal.ip |
Mapeado diretamente. |
cloud_zone |
principal.cloud.availability_zone |
Mapeado diretamente. |
connector_resp_time |
security_result.detection_fields.key: "Tempo de resposta do conector", security_result.detection_fields.value: connector_resp_time |
Mapeado condicionalmente se connector_resp_time não estiver vazio ou for "-". |
content_type |
additional.fields.key: "Content type", additional.fields.value.string_value: content_type |
Mapeado condicionalmente se content_type estiver presente. |
datetime |
metadata.event_timestamp |
Analisado a partir do campo datetime através do formato RFC3339. |
deny_reason |
security_result.summary |
Mapeado diretamente. |
device_type |
principal.platform, principal.platform_version |
Mapeado para WINDOWS, LINUX ou MAC com base na correspondência de regex. O valor não processado é mapeado para principal.platform_version. |
di |
metadata.ingestion_labels.key: "di", metadata.ingestion_labels.value: di |
Mapeado diretamente como uma etiqueta de carregamento. |
error_code |
additional.fields.key: "Error code", additional.fields.value.string_value: error_code |
Mapeado condicionalmente se error_code estiver presente. |
event |
metadata.description |
Mapeado diretamente. |
geo_city |
principal.location.city |
Mapeado diretamente. |
geo_country |
principal.location.country_or_region |
Mapeado diretamente. |
geo_state |
principal.location.state |
Mapeado diretamente. |
groups |
principal.user.group_identifiers |
Mapeado diretamente. |
http_method |
network.http.method |
Mapeado diretamente. |
http_ver |
network.application_protocol, network.application_protocol_version |
Analisado através do grok para extrair o protocolo e a versão. |
idpinfo |
additional.fields.key: "IDP Info", additional.fields.value.string_value: idpinfo |
Mapeado condicionalmente se idpinfo estiver presente. |
internal_host |
additional.fields.key: "Internal host", additional.fields.value.string_value: internal_host |
Mapeado condicionalmente se internal_host estiver presente. |
metadata.log_type |
metadata.log_type |
Codificado de forma rígida como "AKAMAI_EAA". |
metadata.product_name |
metadata.product_name |
Codificado de forma rígida como "AKAMAI_EAA". |
metadata.vendor_name |
metadata.vendor_name |
Codificado de forma rígida como "AKAMAI_EAA". |
metadata.event_type |
metadata.event_type |
Determinado pela lógica: USER_UNCATEGORIZED se uid estiver presente, NETWORK_HTTP se principal.ip e target estiverem definidos ou GENERIC_EVENT caso contrário. |
origin_host |
additional.fields.key: "Origin host", additional.fields.value.string_value: origin_host |
Mapeado condicionalmente se origin_host estiver presente. |
origin_resp_time |
security_result.detection_fields.key: "Tempo de resposta da origem", security_result.detection_fields.value: origin_resp_time |
Mapeado condicionalmente se origin_resp_time não estiver vazio ou for "-". |
os |
principal.platform |
Mapeado para WINDOWS, MAC ou LINUX com base na correspondência de regex. |
port |
target.port |
O valor após os dois pontos no campo app. |
ral |
metadata.description |
Valores concatenados da matriz ral, separados por vírgulas. |
referer |
network.http.referral_url |
Mapeado diretamente. |
resource |
principal.resource.attribute.labels.key: "Resource", principal.resource.attribute.labels.value: resource |
Mapeado condicionalmente se resource estiver presente. |
resource_type |
principal.resource.attribute.labels.key: "Resource Type", principal.resource.attribute.labels.value: resource_type |
Mapeado condicionalmente se resource_type estiver presente. |
rscd |
metadata.ingestion_labels.key: "rscd", metadata.ingestion_labels.value: rscd |
Mapeado diretamente como uma etiqueta de carregamento. |
session_id |
network.session_id |
Mapeado diretamente. |
session_info |
additional.fields.key: "Session info", additional.fields.value.string_value: session_info |
Mapeado condicionalmente se session_info estiver presente. |
state |
principal.location.state |
Mapeado diretamente. |
status_code |
network.http.response_code |
Mapeado diretamente. |
total_resp_time |
security_result.detection_fields.key: "Tempo de resposta total", security_result.detection_fields.value: total_resp_time |
Mapeado condicionalmente se total_resp_time não estiver vazio ou for "-". |
ts |
metadata.event_timestamp |
Analisado a partir do campo ts como milissegundos ou segundos UNIX, se estiver presente, caso contrário, a partir do campo datetime. |
uid |
principal.user.userid |
Mapeado diretamente. |
uip |
principal.ip |
Mapeado diretamente. |
url_path |
target.url |
Mapeado diretamente. |
user_agent |
network.http.user_agent, network.http.parsed_user_agent |
Mapeado e analisado diretamente num campo parsed_user_agent estruturado. |
username |
principal.user.email_addresses ou principal.user.userid |
Mapeado para email_addresses se parecer um email, caso contrário, para userid. |
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais da Google SecOps.