3 审计日志基础:来源、结构与合规意义

搞 BYOK 审计日志异常检测,第一步得搞清楚日志长什么样、从哪来、有什么用。说白了,没有标准的原始日志,什么告警规则都是空中楼阁。这章我带你走一遍三大云厂商的审计日志,看看结构、摸清门道。

3.1 三大云厂商的审计日志来源

先列个清单。大部分企业现在都是多云架构,AWS、Azure、GCP 至少占俩。每家都有自己的审计服务:

  • AWS CloudTrail —— 记录所有 API 调用,包括管理控制台、CLI、SDK、服务内部调用。
  • Azure Monitor (活动日志 + 诊断设置) —— 活动日志记录控制面操作,诊断设置把平台日志发到 Log Analytics 或存储。
  • GCP Cloud Audit Logs —— 分为管理活动、数据访问、系统事件、策略拒绝四类。

我在项目中遇到过客户误以为只开管理事件就够了。结果 BYOK 密钥被偷偷禁用,CloudTrail 里啥都没留下——因为密钥禁用属于数据事件,默认不记录。吃了亏之后我要求所有项目必须开启数据事件记录。

注意: CloudTrail 数据事件会大幅增加日志量,但 BYOK 相关操作(KMS 的 Encrypt/Decrypt/DisableKey)必须监控,别为了省成本漏掉关键链路。

3.2 日志结构剖析

三个平台的日志都是 JSON 格式,但字段名、层级差得挺远。我习惯把它们映射到一个统一 schema,这样后续告警规则不用重复写三套。下面这张图把核心结构画清楚了。

审计日志来源、结构与合规 AWS CloudTrail Azure Activity Log GCP Audit Logs CloudTrail 结构 userIdentity eventTime / eventSource requestParameters responseElements Azure 活动日志结构 caller / operationName properties (keyVault) resourceId / status eventTimestamp GCP Audit Logs 结构 principalEmail methodName / serviceName authenticationInfo request / response (proto) 统一 Schema (JSON) 合规要求:SOC 2 · HIPAA · PCI DSS · GDPR · FedRAMP BYOK 场景必须保留原始审计日志至少 1 年(部分合规要求 7 年)。

3.3 关键字段对比

做异常检测,关注几个字段就够了。我把三家的映射整理成一张表,方便你写解析逻辑时查。

语义AWS CloudTrailAzure Activity LogGCP Audit Logs
操作时间eventTimeeventTimestamptimestamp
操作主体userIdentity.arncallerprincipalEmail
操作名称eventNameoperationNamemethodName
资源标识resources[].ARNresourceIdresourceName
源 IPsourceIPAddressclaims.ipaddrrequestMetadata.callerIp
请求参数requestParameterspropertiesrequest (ProtoJSON)
返回码errorCode / errorMessagestatus.code / status.messageresponse.status
技巧: CloudTrail 的 requestParameters 是 JSON 对象,Azure 的 properties 是键值对,GCP 的 request 是序列化后的 proto。写 Alert 规则时最好先把它们转成扁平 key-value,方便正则匹配。

3.4 合规意义,为什么非记不可?

你想想看,BYOK 密钥是你在云上最后的防线。合规审计要求你要能追溯到:谁、什么时候、对哪个密钥做了什么。具体到框架:

  • SOC 2 —— 必须监控对密钥的未授权访问尝试,记录所有管理操作。
  • HIPAA —— 对包含 PHI 的密钥需启用数据事件日志,保留至少 6 年。
  • PCI DSS v4.0 —— 要求审计日志覆盖所有密钥生命周期操作,且日志不可篡改。
  • GDPR —— 密钥访问日志可能包含个人数据(如用户邮箱),需做脱敏处理。
  • FedRAMP —— 需要日志集中存储,并配置实时告警。

我记得有一次客户过 SOC 2 审计,审计师问:「你 CloudTrail 里的 userIdentity 字段有没有包含角色链?」我们当时只记录了直接调用者,没记录扮演角色。差点被开 observed finding。从那以后我要求所有日志 schema 里必须保留完整的身份链。

避坑: 千万别在日志收集阶段直接过滤掉异常操作——比如 DisableKey、ScheduleKeyDeletion。我见过有人觉得「密钥禁用是常见操作」就降级了告警级别,结果真正被攻击时毫无察觉。这些操作必须触发高优先级告警。

3.5 日志生命周期:收集、存储、保留

搞清楚了结构,还得知道日志怎么流转。我一般把它分成三步:

  1. 收集 —— 开启对应服务的审计开关,配置到 S3/Blob Storage/GCS,或者直接推送到 SIEM(比如 Splunk、ELK)。
  2. 存储 —— 原始 JSON 一定要存一份不可改写的副本。AWS 用 S3 Object Lock、Azure 用不可变存储、GCP 用 Retention Policy。
  3. 保留 —— 按合规要求至少 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") }