Coletar registros do Akamai EAA (Enterprise Application Access)
Este documento explica como ingerir registros do Akamai Enterprise Application Access (EAA) no Google Security Operations usando o Unified Log Streamer (ULS) e o Bindplane da Akamai. O EAA da Akamai produz dados operacionais na forma de registros de acesso, registros de auditoria de administrador, detalhes de autenticação e métricas de integridade do conector. O analisador extrai campos dos registros JSON, realiza transformações de dados, como conversões de string e extração de endereços IP, e mapeia esses campos para a UDM, processando vários tipos de eventos, como NETWORK_HTTP e USER_UNCATEGORIZED, com base na presença de campos específicos. Ele também adiciona metadados, como nomes de fornecedores e produtos, ao evento da UDM.
Antes de começar
Verifique se você tem os pré-requisitos a seguir:
- Uma instância do Google SecOps
- Um host Windows 2016 ou mais recente ou Linux com
systemdpara executar o agente do Bindplane - Linux, macOS ou ambiente em contêineres (Docker/Kubernetes) para executar o Unified Log Streamer
- Se você estiver executando por trás de um proxy, verifique se as portas do firewall estão abertas de acordo com os requisitos do agente Bindplane.
- Locatário do EAA da Akamai com acesso administrativo
- Credenciais da API Akamai (autenticação EdgeGrid):
- Token de acesso
- Token de cliente
- Chave secreta do cliente
- Nome do host base da API (por exemplo,
akab-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx.luna.akamaiapis.net)
Receber o arquivo de autenticação de ingestão do Google SecOps
- Faça login no console do Google SecOps.
- Acesse Configurações do SIEM > Agentes de coleta.
- Baixe o arquivo de autenticação de ingestão. Salve o arquivo de forma segura no sistema em que o Bindplane será instalado.
Receber o ID de cliente do Google SecOps
- Faça login no console do Google SecOps.
- Acesse Configurações do SIEM > Perfil.
- Copie e salve o ID do cliente na seção Detalhes da organização.
Instalar o agente do Bindplane
Instale o agente do Bindplane no seu sistema operacional Windows ou Linux de acordo com as instruções a seguir.
Instalação do Windows
- Abra o Prompt de Comando ou o PowerShell como administrador.
Execute este 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 root ou sudo.
Execute este comando:
sudo sh -c "$(curl -fsSlL https://github.com/observiq/bindplane-agent/releases/latest/download/install_unix.sh)" install_unix.sh
Outros recursos de instalação
- Para mais opções de instalação, consulte este guia de instalação.
Configurar o agente do Bindplane para ingerir o Syslog e enviar ao Google SecOps
Acesse o arquivo de configuração:
- Localize o arquivo
config.yaml. Normalmente, ele fica no diretório/etc/bindplane-agent/no Linux ou no diretório de instalação no Windows. - Abra o arquivo usando um editor de texto (por exemplo,
nano,viou Bloco de Notas).
- Localize o arquivo
Edite o arquivo
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:
- Substitua
<CUSTOMER_ID>pelo ID do cliente real. - Atualize
/path/to/ingestion-authentication-file.jsonpara o caminho em que o arquivo de autenticação foi salvo na seção Receber arquivo de autenticação de ingestão do Google SecOps. 0.0.0.0:5140: o endereço IP e a porta que o Bindplane vai detectar. Ajuste conforme necessário para seu ambiente.
- Substitua
- Substitua:
Reinicie o agente do Bindplane para aplicar as mudanças
Para reiniciar o agente do Bindplane no Linux, execute o seguinte comando:
sudo systemctl restart bindplane-agentPara reiniciar o agente do Bindplane no Windows, use o console Serviços ou insira o seguinte comando:
net stop BindPlaneAgent && net start BindPlaneAgent
Instalar o Akamai Unified Log Streamer
O Unified Log Streamer (ULS) extrai registros do Akamai EAA pela API Enterprise Application Access e os transmite para o Bindplane usando TCP ou UDP.
Instalação do Linux
Faça o download da versão mais recente do ULS:
curl -LO https://github.com/akamai/uls/releases/latest/download/uls-linux-amd64Torne o binário executável:
chmod +x uls-linux-amd64Mova para um local padrão:
sudo mv uls-linux-amd64 /usr/local/bin/uls
Instalação no macOS
Faça o download da versão mais recente do ULS:
curl -LO https://github.com/akamai/uls/releases/latest/download/uls-darwin-amd64Torne o binário executável:
chmod +x uls-darwin-amd64Mova para um local 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
Configurar credenciais do Akamai EdgeGrid
Crie o arquivo de credenciais do EdgeGrid:
mkdir -p ~/.edgerc nano ~/.edgercAdicione 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 arquivo de credenciais:
chmod 600 ~/.edgerc
Substitua:
your-client-secret: sua chave secreta de cliente da Akamai.your-access-token: seu token de acesso da Akamai.your-client-token: seu token de cliente da Akamai.akab-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx.luna.akamaiapis.net: o nome do host base da API Akamai.
Configurar o ULS para transmitir registros do EAA para o BindPlane
Execução da linha de comando (teste)
Execute o ULS com saída TCP para transmitir registros ao agente do Bindplane:
uls --input eaa \
--feed access \
--output tcp \
--host <BINDPLANE_HOST> \
--port 5140 \
--edgerc ~/.edgerc \
--section default
- Substitua:
<BINDPLANE_HOST>: o endereço IP ou o nome do host do servidor que executa o Bindplane5140: a porta configurada no receptortcplogdo Bindplane.
Para transmitir vários tipos de feed, execute instâncias separadas do ULS:
```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 do systemd (produção)
Para implantações de produção, configure o ULS como um serviço do systemd:
Crie um arquivo de configuração do 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 arquivo de serviço do 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.serviceConferir registros:
sudo journalctl -u uls-eaa-access.service -f
Repita as etapas de 1 a 7 para cada tipo de feed adicional (admin, conhealth) criando arquivos de configuração e de serviço separados com nomes diferentes (por exemplo, uls-eaa-admin.service, uls-eaa-conhealth.service).
Implantação do Docker
Crie um arquivo do 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 nome do host do seu servidor Bindplane.
- Substitua
Inicie os contêineres:
docker-compose up -dConferir registros:
docker-compose logs -f
Tabela de mapeamento do UDM
| Campo de registro | Mapeamento do UDM | Lógica |
|---|---|---|
app |
target.application |
O valor depois dos 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: "Tipo de conteúdo", additional.fields.value.string_value: content_type |
Mapeado condicionalmente se content_type estiver presente. |
datetime |
metadata.event_timestamp |
Analisado do campo datetime usando o 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 bruto é mapeado para principal.platform_version. |
di |
metadata.ingestion_labels.key: "di", metadata.ingestion_labels.value: di |
Mapeado diretamente como um rótulo de ingestão. |
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 usando grok para extrair protocolo e 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 |
Fixado no código como "AKAMAI_EAA". |
metadata.product_name |
metadata.product_name |
Fixado no código como "AKAMAI_EAA". |
metadata.vendor_name |
metadata.vendor_name |
Fixado no código 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: "Host de origem", 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 depois dos 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 um rótulo de ingestão. |
session_id |
network.session_id |
Mapeado diretamente. |
session_info |
additional.fields.key: "Informações da sessão", 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 total de resposta", 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 do campo ts como milissegundos ou segundos do UNIX, se presente. Caso contrário, 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 em um campo parsed_user_agent estruturado. |
username |
principal.user.email_addresses ou principal.user.userid |
Mapeado para email_addresses se parecer um e-mail, caso contrário, para userid. |
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.