Akamai EAA (Enterprise Application Access) 로그 수집
이 문서에서는 Akamai의 통합 로그 스트리머 (ULS) 및 Bindplane을 사용하여 Akamai Enterprise Application Access (EAA) 로그를 Google Security Operations로 수집하는 방법을 설명합니다. Akamai EAA는 액세스 로그, 관리자 감사 로그, 인증 세부정보, 커넥터 상태 측정항목의 형태로 운영 데이터를 생성합니다. 파서는 JSON 로그에서 필드를 추출하고, 문자열 변환 및 IP 주소 추출과 같은 데이터 변환을 실행하고, 이러한 필드를 UDM에 매핑하여 특정 필드의 존재 여부에 따라 NETWORK_HTTP 및 USER_UNCATEGORIZED과 같은 다양한 이벤트 유형을 처리합니다. 또한 공급업체 및 제품 이름과 같은 메타데이터를 UDM 이벤트에 추가합니다.
시작하기 전에
다음 기본 요건이 충족되었는지 확인합니다.
- Google SecOps 인스턴스
- Bindplane 에이전트를 실행하는 Windows 2016 이상 또는 Linux 호스트(
systemd) - 통합 로그 스트리머를 실행하기 위한 Linux, macOS 또는 컨테이너화된 환경 (Docker/Kubernetes)
- 프록시 뒤에서 실행하는 경우 Bindplane 에이전트 요구사항에 따라 방화벽 포트가 열려 있는지 확인합니다.
- 관리 액세스 권한이 있는 Akamai EAA 테넌트
- Akamai API 사용자 인증 정보 (EdgeGrid 인증):
- 액세스 토큰
- 클라이언트 토큰
- 클라이언트 보안 비밀번호
- API 기본 호스트 이름 (예:
akab-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx.luna.akamaiapis.net)
Google SecOps 수집 인증 파일 가져오기
- Google SecOps 콘솔에 로그인합니다.
- SIEM 설정 > 수집 에이전트로 이동합니다.
- 수집 인증 파일을 다운로드합니다. Bindplane이 설치될 시스템에 파일을 안전하게 저장합니다.
Google SecOps 고객 ID 가져오기
- Google SecOps 콘솔에 로그인합니다.
- SIEM 설정 > 프로필로 이동합니다.
- 조직 세부정보 섹션에서 고객 ID를 복사하여 저장합니다.
Bindplane 에이전트 설치
다음 안내에 따라 Windows 또는 Linux 운영체제에 Bindplane 에이전트를 설치합니다.
Windows 설치
- 명령 프롬프트 또는 PowerShell을 관리자로 엽니다.
다음 명령어를 실행합니다.
msiexec /i "https://github.com/observIQ/bindplane-agent/releases/latest/download/observiq-otel-collector.msi" /quiet
Linux 설치
- 루트 또는 sudo 권한으로 터미널을 엽니다.
다음 명령어를 실행합니다.
sudo sh -c "$(curl -fsSlL https://github.com/observiq/bindplane-agent/releases/latest/download/install_unix.sh)" install_unix.sh
추가 설치 리소스
- 추가 설치 옵션은 이 설치 가이드를 참고하세요.
Syslog를 수집하여 Google SecOps로 전송하도록 Bindplane 에이전트 구성
구성 파일에 액세스합니다.
config.yaml파일을 찾습니다. 일반적으로 Linux에서는/etc/bindplane-agent/디렉터리에 있고 Windows에서는 설치 디렉터리에 있습니다.- 텍스트 편집기 (예:
nano,vi, 메모장)를 사용하여 파일을 엽니다.
다음과 같이
config.yaml파일을 수정합니다.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- 다음을 바꿉니다.
<CUSTOMER_ID>를 실제 고객 ID로 바꿉니다.- Google SecOps 수집 인증 파일 가져오기 섹션에서 인증 파일이 저장된 경로로
/path/to/ingestion-authentication-file.json를 업데이트합니다. 0.0.0.0:5140: Bindplane이 리슨할 IP 주소와 포트입니다. 환경에 맞게 필요에 따라 조정합니다.
- 다음을 바꿉니다.
Bindplane 에이전트를 다시 시작하여 변경사항 적용
Linux에서 Bindplane 에이전트를 다시 시작하려면 다음 명령어를 실행합니다.
sudo systemctl restart bindplane-agentWindows에서 Bindplane 에이전트를 다시 시작하려면 서비스 콘솔을 사용하거나 다음 명령어를 입력하면 됩니다.
net stop BindPlaneAgent && net start BindPlaneAgent
Akamai Unified Log Streamer 설치
통합 로그 스트리머 (ULS)는 Enterprise Application Access API를 통해 Akamai EAA에서 로그를 가져와 TCP 또는 UDP를 사용하여 Bindplane으로 스트리밍합니다.
Linux 설치
최신 ULS 출시 버전을 다운로드합니다.
curl -LO https://github.com/akamai/uls/releases/latest/download/uls-linux-amd64바이너리를 실행 가능하게 만듭니다.
chmod +x uls-linux-amd64표준 위치로 이동합니다.
sudo mv uls-linux-amd64 /usr/local/bin/uls
macOS 설치
최신 ULS 출시 버전을 다운로드합니다.
curl -LO https://github.com/akamai/uls/releases/latest/download/uls-darwin-amd64바이너리를 실행 가능하게 만듭니다.
chmod +x uls-darwin-amd64표준 위치로 이동합니다.
sudo mv uls-darwin-amd64 /usr/local/bin/uls
Docker 설치
공식 ULS Docker 이미지를 가져옵니다.
docker pull akamai/uls:latest
Akamai EdgeGrid 사용자 인증 정보 구성
EdgeGrid 사용자 인증 정보 파일을 만듭니다.
mkdir -p ~/.edgerc nano ~/.edgerc다음 형식으로 Akamai API 사용자 인증 정보를 추가합니다.
[default] client_secret = your-client-secret host = akab-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx.luna.akamaiapis.net access_token = your-access-token client_token = your-client-token사용자 인증 정보 파일을 보호합니다.
chmod 600 ~/.edgerc
다음을 바꿉니다.
your-client-secret: Akamai 클라이언트 보안 비밀번호입니다.your-access-token: Akamai 액세스 토큰입니다.your-client-token: Akamai 클라이언트 토큰입니다.akab-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx.luna.akamaiapis.net: Akamai API 기본 호스트 이름입니다.
EAA 로그를 BindPlane으로 스트리밍하도록 ULS 구성
명령줄 실행 (테스트)
TCP 출력을 사용하여 ULS를 실행하여 로그를 Bindplane 에이전트로 스트리밍합니다.
uls --input eaa \
--feed access \
--output tcp \
--host <BINDPLANE_HOST> \
--port 5140 \
--edgerc ~/.edgerc \
--section default
- 다음을 바꿉니다.
<BINDPLANE_HOST>: Bindplane을 실행하는 서버의 IP 주소 또는 호스트 이름5140: Bindplane의tcplog수신기에서 구성된 포트
여러 피드 유형을 스트리밍하려면 별도의 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
```
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=defaultsystemd 서비스 파일을 만듭니다.
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/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.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
이름이 다른 별도의 구성 및 서비스 파일 (예: uls-eaa-admin.service, uls-eaa-conhealth.service)을 만들어 추가 피드 유형 (admin, conhealth)마다 1~7단계를 반복합니다.
Docker 배포
Docker Compose 파일을 만듭니다.
nano 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 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<BINDPLANE_HOST>을 Bindplane 서버의 IP 주소 또는 호스트 이름으로 바꿉니다.
컨테이너를 시작합니다.
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.received_bytes |
직접 매핑됩니다. |
bytes_out |
network.sent_bytes |
직접 매핑됩니다. |
cc |
principal.location.country_or_region |
직접 매핑됩니다. |
client_id |
additional.fields.key: '클라이언트 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: '커넥터 응답 시간', security_result.detection_fields.value: connector_resp_time |
connector_resp_time이 비어 있지 않거나 '-'인 경우 조건부로 매핑됩니다. |
content_type |
additional.fields.key: '콘텐츠 유형', additional.fields.value.string_value: content_type |
content_type가 있는 경우 조건부로 매핑됩니다. |
datetime |
metadata.event_timestamp |
RFC3339 형식을 사용하여 datetime 필드에서 파싱됩니다. |
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 정보', 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 |
uid이 있으면 USER_UNCATEGORIZED, principal.ip과 target이 모두 설정되어 있으면 NETWORK_HTTP, 그 외의 경우에는 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: '리소스 유형', 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: '세션 정보', 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 전문가에게 문의하여 답변을 받으세요.