Azure WAF 로그 수집
다음에서 지원:
Google SecOps
SIEM
이 문서에서는 Azure 스토리지 계정을 사용하여 Azure 웹 애플리케이션 방화벽 (WAF) 로그를 Google Security Operations로 내보내는 방법을 설명합니다. 파서는 JSON 형식의 로그를 처리하여 UDM으로 변환합니다. 각 레코드를 반복하고 특정 필드를 UDM 속성에 매핑하여 records 배열이 포함된 로그를 처리합니다. records 배열이 없으면 파서는 로그를 단일 이벤트로 처리하여 필드를 추출하고 적절하게 매핑합니다.
시작하기 전에
- Google SecOps 인스턴스가 있는지 확인합니다.
- 활성 Azure 테넌트가 있는지 확인합니다.
- Azure에 대한 권한이 있는지 확인합니다.
Azure 스토리지 계정 구성
- Azure Console에서 스토리지 계정을 검색합니다.
- 만들기를 클릭합니다.
- 다음 입력 매개변수의 값을 지정합니다.
- 구독: 구독을 선택합니다.
- 리소스 그룹: 리소스 그룹을 선택합니다.
- 리전: 리전을 선택합니다.
- 실적: 실적을 선택합니다 (표준 권장).
- 중복성: 중복성을 선택합니다 (GRS 또는 LRS 권장).
- 스토리지 계정 이름: 새 스토리지 계정의 이름을 입력합니다.
- 검토 + 만들기를 클릭합니다.
- 계정 개요를 검토하고 만들기를 클릭합니다.
- 스토리지 계정 개요 페이지의 보안 + 네트워킹에서 액세스 키 하위 메뉴를 선택합니다.
- key1 또는 key2 옆에 있는 표시를 클릭합니다.
- 클립보드에 복사를 클릭하여 키를 복사합니다.
- 나중에 사용할 수 있도록 키를 안전한 위치에 저장합니다.
- 스토리지 계정 개요 페이지의 설정에서 엔드포인트 하위 메뉴를 선택합니다.
- 클립보드에 복사를 클릭하여 Blob 서비스 엔드포인트 URL(예:
https://<storageaccountname>.blob.core.windows.net
)을 복사합니다. - 나중에 사용할 수 있도록 엔드포인트 URL을 안전한 위치에 저장합니다.
Azure WAF 로그의 로그 내보내기 구성
- 권한이 있는 계정을 사용하여 Azure 포털에 로그인합니다.
- 웹 애플리케이션 방화벽 (WAF) 규칙으로 이동하여 모니터링할 WAF를 선택합니다.
- 모니터링 > 진단 설정을 선택합니다.
- + 진단 설정 추가를 클릭합니다.
- 진단 설정을 설명하는 이름을 입력합니다.
- allLogs를 선택합니다.
- 대상으로 스토리지 계정에 아카이브 체크박스를 선택합니다.
- 구독 및 스토리지 계정을 지정합니다.
- 저장을 클릭합니다.
Azure WAF 로그를 수집하도록 Google SecOps에서 피드 구성
- SIEM 설정 > 피드로 이동합니다.
- 새로 추가를 클릭합니다.
- 피드 이름 필드에 피드 이름을 입력합니다(예: Azure WAF 로그).
- 소스 유형으로 Microsoft Azure Blob Storage를 선택합니다.
- 로그 유형으로 Azure WAF를 선택합니다.
- 다음을 클릭합니다.
다음 입력 매개변수의 값을 지정합니다.
- Azure URI: blob 엔드포인트 URL입니다.
ENDPOINT_URL/BLOB_NAME
- 다음을 바꿉니다.
ENDPOINT_URL
: blob 엔드포인트 URL (https://<storageaccountname>.blob.core.windows.net
)BLOB_NAME
: blob의 이름입니다 (예:<logname>-logs
).
- 다음을 바꿉니다.
- URI: 로그 스트림 구성 (단일 파일 | 디렉터리 | 하위 디렉터리가 포함된 디렉터리)에 따라 URI 유형을 선택합니다.
소스 삭제 옵션: 원하는 삭제 옵션을 선택합니다.
공유 키: Azure Blob Storage의 액세스 키입니다.
애셋 네임스페이스: 애셋 네임스페이스입니다.
수집 라벨: 이 피드의 이벤트에 적용할 라벨입니다.
- Azure URI: blob 엔드포인트 URL입니다.
다음을 클릭합니다.
확정 화면에서 새 피드 구성을 검토한 다음 제출을 클릭합니다.
UDM 매핑 표
로그 필드 | UDM 매핑 | 논리 |
---|---|---|
backendPoolName |
additional.fields[?key=='backendPoolName'].value.string_value |
이 값은 원시 로그의 backendPoolName 필드에서 가져옵니다. |
backendSettingName |
additional.fields[?key=='backendSettingName'].value.string_value |
이 값은 원시 로그의 backendSettingName 필드에서 가져옵니다. |
category |
metadata.product_event_type |
이 값은 원시 로그의 category 필드에서 가져옵니다. |
EventEnqueuedUtcTime |
additional.fields[?key=='EventEnqueuedUtcTime'].value.string_value |
records 필드가 있는 경우 원시 로그의 EventEnqueuedUtcTime 필드에서 값을 가져옵니다. |
EventProcessedUtcTime |
additional.fields[?key=='EventProcessedUtcTime'].value.string_value |
records 필드가 있는 경우 원시 로그의 EventProcessedUtcTime 필드에서 값을 가져옵니다. |
operationName |
additional.fields[?key=='operationName'].value.string_value |
이 값은 원시 로그의 operationName 필드에서 가져옵니다. |
properties.action |
additional.fields[?key=='action'].value.string_value |
records 필드가 있는 경우 원시 로그의 properties.action 필드에서 값을 가져옵니다. |
properties.action |
security_result.action_details |
records 필드가 없으면 원시 로그의 properties.action 필드에서 값을 가져옵니다. |
properties.clientIP , properties.clientIp |
principal.asset.ip , principal.ip |
이 값은 원시 로그의 properties.clientIP 또는 properties.clientIp 필드에서 가져와 clientIP 를 우선시합니다. |
properties.clientPort |
principal.port |
이 값은 원시 로그의 properties.clientPort 필드에서 가져옵니다. |
properties.clientResponseTime |
principal.resource.attribute.labels[?key=='Client Response Time'].value |
records 필드가 없으면 원시 로그의 properties.clientResponseTime 필드에서 값을 가져옵니다. |
properties.details.data |
additional.fields[?key=='Properties data'].value.string_value |
records 필드가 있는 경우 원시 로그의 properties.details.data 필드에서 값을 가져옵니다. |
properties.details.file |
principal.process.file.full_path |
records 필드가 없으면 원시 로그의 properties.details.file 필드에서 값을 가져옵니다. |
properties.details.matches[].matchVariableName , properties.details.matches[].matchVariableValue |
additional.fields[?key.startsWith('%{idx} ')].value.string_value |
이 값은 원시 로그의 properties.details.matches 배열에서 가져옵니다. UDM의 key 는 색인 (idx )과 matchVariableName 를 사용하여 구성됩니다. value 는 matchVariableValue 에서 가져옵니다. |
properties.details.message |
metadata.description |
이 값은 백슬래시와 따옴표를 삭제한 후 원시 로그의 properties.details.message 필드에서 가져옵니다. |
properties.details.msg |
metadata.description |
records 필드가 있는 경우 원시 로그의 properties.details.msg 필드에서 값을 가져옵니다. |
properties.httpMethod |
network.http.method |
이 값은 원시 로그의 properties.httpMethod 필드에서 가져옵니다. |
properties.httpStatus |
network.http.response_code |
이 값은 원시 로그의 properties.httpStatus 필드에서 가져옵니다. |
properties.httpVersion |
network.application_protocol |
properties.httpVersion 필드에 HTTP 가 포함되면 값 HTTP 가 할당됩니다. |
properties.host , properties.hostname , properties.originalHost |
principal.asset.hostname , principal.hostname |
값은 properties.originalHost , properties.host , properties.hostname 중 하나에서 가져와서 그 순서대로 우선순위를 지정합니다. |
properties.policyId |
security_result.detection_fields[?key=='policyId'].value |
이 값은 원시 로그의 properties.policyId 필드에서 가져옵니다. |
properties.policyMode |
security_result.detection_fields[?key=='policyMode'].value |
records 필드가 있는 경우 원시 로그의 properties.policyMode 필드에서 값을 가져옵니다. |
properties.policy |
additional.fields[?key=='Properties policy'].value.string_value |
records 필드가 있는 경우 원시 로그의 properties.policy 필드에서 값을 가져옵니다. |
properties.receivedBytes |
network.received_bytes |
이 값은 원시 로그의 properties.receivedBytes 필드에서 가져옵니다. |
properties.requestUri |
target.url |
이 값은 원시 로그의 properties.requestUri 필드에서 가져옵니다. |
properties.ruleId |
security_result.rule_id |
이 값은 원시 로그의 properties.ruleId 필드에서 가져옵니다. |
properties.ruleName |
security_result.rule_name |
records 필드가 있는 경우 원시 로그의 properties.ruleName 필드에서 값을 가져옵니다. |
properties.ruleName , ruleSetType |
security_result.rule_name |
값은 properties.ruleName 필드에서 가져오거나, 비어 있는 경우 records 필드가 없는 경우 원시 로그의 ruleSetType 필드에서 가져옵니다. |
properties.ruleSetVersion |
security_result.detection_fields[?key=='ruleSetVersion'].value |
이 값은 원시 로그의 properties.ruleSetVersion 필드에서 가져옵니다. |
properties.sentBytes |
network.sent_bytes |
이 값은 원시 로그의 properties.sentBytes 필드에서 가져옵니다. |
properties.serverResponseLatency |
additional.fields[?key=='Server Response Latency'].value.string_value |
records 필드가 없으면 원시 로그의 properties.serverResponseLatency 필드에서 값을 가져옵니다. |
properties.serverRouted |
target.asset.ip , target.ip , target.port |
IP 및 포트는 properties.serverRouted 필드에서 추출됩니다. |
properties.sslCipher |
network.tls.cipher |
이 값은 원시 로그의 properties.sslCipher 필드에서 가져옵니다. |
properties.sslClientCertificateIssuerName |
network.tls.server.certificate.issuer |
이 값은 원시 로그의 properties.sslClientCertificateIssuerName 필드에서 가져옵니다. |
properties.sslProtocol |
network.tls.version |
이 값은 원시 로그의 properties.sslProtocol 필드에서 가져옵니다. |
properties.timeTaken |
additional.fields[?key=='Properties Timetaken'].value.string_value |
records 필드가 없으면 원시 로그의 properties.timeTaken 필드에서 값을 가져옵니다. |
properties.trackingReference |
additional.fields[?key=='trackingReference'].value.string_value |
records 필드가 있는 경우 원시 로그의 properties.trackingReference 필드에서 값을 가져옵니다. |
properties.transactionId |
network.session_id |
이 값은 원시 로그의 properties.transactionId 필드에서 가져옵니다. |
properties.userAgent |
network.http.user_agent |
이 값은 원시 로그의 properties.userAgent 필드에서 가져옵니다. |
properties.WAFEvaluationTime |
additional.fields[?key=='Properties WAFEvaluationTime'].value.string_value |
records 필드가 없으면 원시 로그의 properties.WAFEvaluationTime 필드에서 값을 가져옵니다. |
properties.WAFMode |
additional.fields[?key=='Properties WAFMode'].value.string_value |
records 필드가 없으면 원시 로그의 properties.WAFMode 필드에서 값을 가져옵니다. |
rec.category |
metadata.product_event_type |
records 필드가 있는 경우 원시 로그의 rec.category 필드에서 값을 가져옵니다. |
rec.operationName |
additional.fields[?key=='operationName'].value.string_value |
records 필드가 있는 경우 원시 로그의 rec.operationName 필드에서 값을 가져옵니다. |
rec.properties.clientIP , rec.properties.clientIp |
principal.asset.ip , principal.ip |
값은 원시 로그의 rec.properties.clientIP 또는 rec.properties.clientIp 필드에서 가져오며, records 필드가 있는 경우 clientIP 에 우선순위를 둡니다. |
rec.properties.clientPort |
principal.port |
records 필드가 있는 경우 원시 로그의 rec.properties.clientPort 필드에서 값을 가져옵니다. |
rec.properties.host |
principal.asset.hostname , principal.hostname |
records 필드가 있는 경우 원시 로그의 rec.properties.host 필드에서 값을 가져옵니다. |
rec.properties.policy |
additional.fields[?key=='Properties policy'].value.string_value |
records 필드가 있는 경우 원시 로그의 rec.properties.policy 필드에서 값을 가져옵니다. |
rec.properties.requestUri |
target.url |
records 필드가 있는 경우 원시 로그의 rec.properties.requestUri 필드에서 값을 가져옵니다. |
rec.properties.ruleName |
security_result.rule_name |
records 필드가 있는 경우 원시 로그의 rec.properties.ruleName 필드에서 값을 가져옵니다. |
rec.properties.trackingReference |
additional.fields[?key=='trackingReference'].value.string_value |
records 필드가 있는 경우 원시 로그의 rec.properties.trackingReference 필드에서 값을 가져옵니다. |
rec.resourceId |
target.resource.id |
records 필드가 있는 경우 원시 로그의 rec.resourceId 필드에서 값을 가져옵니다. |
rec.time |
metadata.event_timestamp |
records 필드가 있는 경우 원시 로그의 rec.time 필드에서 값을 가져옵니다. |
resourceId |
target.resource.id |
records 필드가 없으면 원시 로그의 resourceId 필드에서 값을 가져옵니다. |
timeStamp |
metadata.event_timestamp |
records 필드가 없으면 원시 로그의 timeStamp 필드에서 값을 가져옵니다. |
해당 사항 없음 | metadata.event_type |
사용자 (호스트 이름 또는 클라이언트 IP)와 대상 IP가 모두 있는 경우 값은 NETWORK_CONNECTION 로 설정됩니다. 주 구성원이 있지만 대상 IP가 없는 경우 STATUS_UPDATE 로 설정됩니다. 그렇지 않으면 기본값은 GENERIC_EVENT 또는 event_type 필드의 값입니다. |
해당 사항 없음 | metadata.log_type |
값은 AZURE_WAF 로 하드코딩되어 있습니다. |
해당 사항 없음 | metadata.product_name |
값은 Azure WAF Logs 로 하드코딩되어 있습니다. |
해당 사항 없음 | metadata.vendor_name |
값은 Microsoft 로 하드코딩되어 있습니다. |
해당 사항 없음 | security_result.action |
properties.action 이 Matched 이면 값이 ALLOW 로 설정되고 properties.action 이 Block 이면 BLOCK 로 설정됩니다. |
변경사항
2024-04-07
개선사항:
rec.properties.clientIp
를principal.ip
에 매핑했습니다.- 상태 데이터에
rec_properties_trackingReference
,rec_properties_host
,rec_properties_policyMode
,rec_properties_ruleName
,rec_properties_policy
,rec_properties_details_msg
,rec_properties_clientIP
,rec_time
를 정의했습니다.
2023-07-14
개선사항:
- JSON 로그를 처리하는
for
루프를 추가했습니다.
2023-02-28
개선사항:
properties.ruleName
를security_result.rule_name
에 매핑했습니다.properties.action
를security_result.action
에 매핑했습니다.properties.clientPort
,properties.httpStatus
,properties.receivedBytes
,properties.sentBytes
,properties.clientResponseTime
,properties.timeTaken
에 관한 on_error 검사를 추가했습니다.
2022-10-22
- 새로 생성된 파서
도움이 더 필요하신가요? 커뮤니티 회원 및 Google SecOps 전문가의 답변을 받으세요.