3 审计日志基础:来源、结构与合规意义
搞 BYOK 审计日志异常检测,第一步得搞清楚日志长什么样、从哪来、有什么用。说白了,没有标准的原始日志,什么告警规则都是空中楼阁。这章我带你走一遍三大云厂商的审计日志,看看结构、摸清门道。
3.1 三大云厂商的审计日志来源
先列个清单。大部分企业现在都是多云架构,AWS、Azure、GCP 至少占俩。每家都有自己的审计服务:
- AWS CloudTrail —— 记录所有 API 调用,包括管理控制台、CLI、SDK、服务内部调用。
- Azure Monitor (活动日志 + 诊断设置) —— 活动日志记录控制面操作,诊断设置把平台日志发到 Log Analytics 或存储。
- GCP Cloud Audit Logs —— 分为管理活动、数据访问、系统事件、策略拒绝四类。
我在项目中遇到过客户误以为只开管理事件就够了。结果 BYOK 密钥被偷偷禁用,CloudTrail 里啥都没留下——因为密钥禁用属于数据事件,默认不记录。吃了亏之后我要求所有项目必须开启数据事件记录。
3.2 日志结构剖析
三个平台的日志都是 JSON 格式,但字段名、层级差得挺远。我习惯把它们映射到一个统一 schema,这样后续告警规则不用重复写三套。下面这张图把核心结构画清楚了。
3.3 关键字段对比
做异常检测,关注几个字段就够了。我把三家的映射整理成一张表,方便你写解析逻辑时查。
| 语义 | AWS CloudTrail | Azure Activity Log | GCP Audit Logs |
|---|---|---|---|
| 操作时间 | eventTime | eventTimestamp | timestamp |
| 操作主体 | userIdentity.arn | caller | principalEmail |
| 操作名称 | eventName | operationName | methodName |
| 资源标识 | resources[].ARN | resourceId | resourceName |
| 源 IP | sourceIPAddress | claims.ipaddr | requestMetadata.callerIp |
| 请求参数 | requestParameters | properties | request (ProtoJSON) |
| 返回码 | errorCode / errorMessage | status.code / status.message | response.status |
3.4 合规意义,为什么非记不可?
你想想看,BYOK 密钥是你在云上最后的防线。合规审计要求你要能追溯到:谁、什么时候、对哪个密钥做了什么。具体到框架:
- SOC 2 —— 必须监控对密钥的未授权访问尝试,记录所有管理操作。
- HIPAA —— 对包含 PHI 的密钥需启用数据事件日志,保留至少 6 年。
- PCI DSS v4.0 —— 要求审计日志覆盖所有密钥生命周期操作,且日志不可篡改。
- GDPR —— 密钥访问日志可能包含个人数据(如用户邮箱),需做脱敏处理。
- FedRAMP —— 需要日志集中存储,并配置实时告警。
我记得有一次客户过 SOC 2 审计,审计师问:「你 CloudTrail 里的 userIdentity 字段有没有包含角色链?」我们当时只记录了直接调用者,没记录扮演角色。差点被开 observed finding。从那以后我要求所有日志 schema 里必须保留完整的身份链。
3.5 日志生命周期:收集、存储、保留
搞清楚了结构,还得知道日志怎么流转。我一般把它分成三步:
- 收集 —— 开启对应服务的审计开关,配置到 S3/Blob Storage/GCS,或者直接推送到 SIEM(比如 Splunk、ELK)。
- 存储 —— 原始 JSON 一定要存一份不可改写的副本。AWS 用 S3 Object Lock、Azure 用不可变存储、GCP 用 Retention Policy。
- 保留 —— 按合规要求至少 1 年,金融场景建议 7 年。我习惯在不同保留期的桶里做分层:热数据 30 天用于实时告警,冷数据长期归档。
核心原则: 审计日志的完整性 > 实时性。宁可延迟 5 分钟,不能丢一条记录。
3.6 一个真实案例:用 CloudTrail 日志发现 BYOK 密钥泄露
去年有个客户突然发现 KMS 调用量暴涨。我们用 CloudTrail 日志查了 eventTime 和 sourceIPAddress,发现同一个 AWS 账户 ID 在两个不同的 region 同时加密同一个密钥。正常业务只在一个 region 跑——这就是典型的密钥泄露信号。另外,客户端 IP 来自一个之前从未出现过的国家。
我们在 Alert 规则里加了两个条件:
- 同一密钥在 5 分钟内被两个不同 region 的实例调用。
- sourceIPAddress 的地理位置不在允许列表。
第一个条件直接命中,然后我们手动禁用了密钥、撤销了访问权限。整个流程跑了两个项目后,我把它固化成了标准告警模板。
3.7 你接下来该做什么?
别急着写规则。先把你环境里三大云审计日志的 schema 拿到手,对照上面的表格做一次字段映射。推荐用 Python 写个小解析器,读一条 CloudTrail 日志、一条 Azure 活动日志、一条 GCP 审计日志,打印出统一格式。这一步做扎实了,后面写告警逻辑水到渠成。
# 伪代码示例:解析 CloudTrail 日志并提取关键字段
import json
def parse_cloudtrail(log_line):
event = json.loads(log_line)
return {
"time": event.get("eventTime"),
"actor": event.get("userIdentity", {}).get("arn"),
"action": event.get("eventName"),
"resource": [r.get("ARN") for r in event.get("resources", [])],
"source_ip": event.get("sourceIPAddress"),
"error": event.get("errorCode")
}