收集 Azure WAF 日志
支持的平台:
Google SecOps
SIEM
本文档介绍了如何使用 Azure 存储账号将 Azure Web 应用防火墙 (WAF) 日志导出到 Google 安全运营中心。解析器会处理 JSON 格式的日志,将其转换为 UDM。它会通过迭代每个记录并将特定字段映射到 UDM 属性来处理包含 records 数组的日志。如果缺少 records 数组,解析器会将日志作为单个事件进行处理,并相应地提取和映射字段。
准备工作
- 确保您拥有 Google SecOps 实例。
- 确保您拥有有效的 Azure 租户。
- 确保您拥有对 Azure 的特权访问权限。
配置 Azure 存储账号
- 在 Azure 控制台中,搜索存储账号。
- 点击创建。
- 为以下输入参数指定值:
- 订阅:选择相应订阅。
- 资源组:选择资源组。
- 地区:选择地区。
- 效果:选择效果(推荐“标准”)。
- 冗余:选择冗余级别(建议使用 GRS 或 LRS)。
- 存储账号名称:为新存储账号输入名称。
- 点击 Review + create(检查 + 创建)。
- 查看账号概览,然后点击创建。
- 在存储账号概览页面上,选择安全 + 网络中的访问密钥子菜单。
- 点击 key1 或 key2 旁边的显示。
- 点击复制到剪贴板以复制密钥。
- 将密钥保存在安全的位置,以备日后使用。
- 在存储账号概览页面中,选择设置中的端点子菜单。
- 点击复制到剪贴板,复制 Blob 服务端点网址;例如
https://<storageaccountname>.blob.core.windows.net
。 - 将端点网址保存在安全的位置,以备日后使用。
为 Azure WAF 日志配置日志导出
- 使用特权账号登录 Azure 门户。
- 前往 Web 应用防火墙 (WAF) 规则,然后选择要监控的 WAF。
- 依次选择 Monitoring > Diagnostic Settings。
- 点击 + 添加诊断设置。
- 为诊断设置输入描述性名称。
- 选择 allLogs。
- 选择归档到存储账号复选框作为目标位置。
- 指定订阅和存储空间账号。
- 点击保存。
在 Google SecOps 中配置 Feed 以提取 Azure WAF 日志
- 依次前往 SIEM 设置 > Feed。
- 点击新增。
- 在 Feed 名称字段中,输入 Feed 的名称;例如,Azure WAF 日志。
- 选择 Microsoft Azure Blob Storage 作为来源类型。
- 选择 Azure WAF 作为日志类型。
- 点击下一步。
为以下输入参数指定值:
- Azure URI:Blob 端点网址。
ENDPOINT_URL/BLOB_NAME
- 替换以下内容:
ENDPOINT_URL
:blob 端点网址 (https://<storageaccountname>.blob.core.windows.net
)BLOB_NAME
:blob 的名称(例如<logname>-logs
)
- 替换以下内容:
- URI 是:根据日志流配置选择 URI 类型(单个文件 | 目录 | 包含子目录的目录)。
来源删除选项:根据您的偏好选择删除选项。
共享密钥:Azure Blob Storage 的访问密钥。
资源命名空间:资源命名空间。
提取标签:要应用于此 Feed 中的事件的标签。
- Azure URI:Blob 端点网址。
点击下一步。
在最终确定界面中查看新的 Feed 配置,然后点击提交。
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.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 字段;如果该字段为空,则取自原始日志中的 ruleSetType 字段(如果 records 字段不存在)。 |
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
增强功能:
- 添加了
for
循环来处理 JSON 日志。
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 专业人士寻求解答。