日志格式详解:五大核心字段
说到KMS审计日志,我先坦白一件事。刚入行那会儿,我盯着一条加密操作的日志,愣是看了五分钟没看懂。不是我不认识英文,而是字段太多,结构太乱。后来我总结了一个规律——不管哪家云厂商,核心字段就那么五个。搞懂了它们,后面所有巡检工作就能稳稳站住脚。
五大核心字段速览
- 时间戳——什么时候发生的
- 操作类型——干了什么
- 身份信息——谁干的
- 资源标识——对哪个资源干的
- 请求上下文——附加环境信息(客户端IP、UserAgent等)
1. 时间戳:所有分析的锚点
如果你问我,审计日志里最重要的字段是什么?我选时间戳。没有准确的时间,你根本没法做时序分析,更别说溯源了。
KMS审计日志中的时间戳,各家云厂商表达方式不太一样。我整理了一个对比表格,方便你对照。
| 云厂商 | 字段名 | 格式示例 | 时区 |
|---|---|---|---|
| AWS CloudTrail | eventTime | 2025-06-15T08:30:21Z | UTC |
| 阿里云操作审计 | eventTime | 2025-06-15T16:30:21+08:00 | 东八区 |
| 华为云 CTS | timestamp | 2025-06-15T08:30:21.123Z | UTC |
| 腾讯云 CloudAudit | eventTimestamp | 2025-06-15 16:30:21 | CST(东八区) |
避坑指南
我曾经帮一个客户排查异常访问,发现日志里某个操作在凌晨3点发生。客户说不可能,他们晚上没人值班。后来一查,问题是日志是UTC时间,他按北京时间看的。时区转换差了8个小时,虚惊一场。
建议:所有巡检脚本里,强制把时间戳统一转成UTC。别依赖云厂商自带的时区字段,自己做归一化最可靠。
2. 操作类型:到底干了什么
操作类型字段一般叫 eventName 或者 action。KMS 的操作大概能分成三类,我习惯这样记:
- 密钥管理操作:CreateKey、DeleteKey、EnableKey、DisableKey、ScheduleKeyDeletion
- 密钥使用操作:Encrypt、Decrypt、GenerateDataKey、Sign、Verify
- 配置变更操作:PutKeyPolicy、TagResource、RotateKey、UpdateAlias
说实话,大部分企业的KMS操作里,Decrypt 和 GenerateDataKey 占了70%以上。如果你巡检时发现突然有一堆 CreateKey,而且是在非工作时间由非管理员账号触发的——嗯,你要警惕了。
注意:我见过一些团队只关注失败的操作(AccessDenied、InvalidKeyId),但实际上,成功操作的异常频率变化才是更大的危险信号。举个例子,正常的Decrypt操作一天可能几百次,某天突然飙到几万次,那可能是有人在暴力拉取你的数据。
3. 身份信息:谁在操作
这个字段在审计里叫 userIdentity 或者 caller。结构比较复杂,我拆开给你看。
一个典型的身份信息长这样:
{
"userIdentity": {
"type": "AssumedRole",
"principalId": "AROAEXAMPLEID:alice",
"arn": "arn:aws:iam::123456789012:role/AdminRole/alice",
"accountId": "123456789012",
"userName": "alice",
"invokedBy": "signin.amazonaws.com"
}
}
这里有几个关键点你得盯死:
- type:Root(根用户)、IAMUser(IAM用户)、AssumedRole(角色扮演)、FederatedUser(联合身份)
- principalId:唯一主体标识,和用户名要对照着看
- invokedBy:如果是控制台操作,这个字段会告诉你从哪个服务发起的
我个人习惯是,先过滤掉 Root 用户的操作。如果发现 Root 在执行KMS操作,那就是严重的事故——最佳实践中 Root 只用来注册账号,平时根本不应该有活动。
巡检口诀:
一看type是不是Root,二看principalId是不是预期人员,三看invokedBy是不是控制台——如果是,查查这个人那时候为什么手动操作密钥。
4. 资源标识:对哪个密钥下手了
资源标识通常以 resources 数组的形式出现。在KMS日志里,keyId 是最核心的字段。
举个例子,一条日志的 JSON 片段:
"resources": [
{
"accountId": "123456789012",
"ARN": "arn:aws:kms:us-east-1:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab",
"type": "AWS::KMS::Key"
}
]
你想想看,如果你有1000个密钥,每天产生海量日志。巡检时怎么快速发现异常?我的做法是建一个密钥白名单。每个业务线允许访问哪些密钥,写死在巡检脚本里。一旦出现白名单之外的密钥访问,立刻告警。
我曾经踩过一个坑:某次巡检发现一个密钥的Decrypt请求暴增,查了三天才发现是旧版SDK里硬编码了过期的密钥ID。那个密钥已经被轮转了,但应用还在用旧的。从那以后,我就在资源标识字段上加了轮转周期检测——如果某个密钥的使用频率在轮转后仍然持续,那说明业务方没更新SDK。
5. 请求上下文:最后一层防护
上下文信息一般包括 sourceIPAddress、userAgent、requestParameters 等。看起来是「附加信息」,但关键时刻能救命。
举个例子:你看到一个操作是 Decrypt,身份信息是正常的 IAM 用户,操作对象是常用的密钥。一切看起来都正常。但你再看看 sourceIPAddress——这个用户的 IP 一直在上海,突然变成了某个国外的机房。是本人出差了?还是账号被盗了?
上下文信息就是帮你做这个判断的。
| 字段名 | 含义 | 巡检关注点 |
|---|---|---|
| sourceIPAddress | 请求来源IP | 是否在白名单内;是否有异常地域跨跳 |
| userAgent | 客户端标识 | 是否是已知SDK;是否出现未知UA |
| requestParameters | 请求参数明细 | 是否传递了异常参数(如空加密上下文) |
| responseElements | 响应信息 | 是否有错误码;延迟是否异常 |
一条完整的日志长什么样
咱们把上面五个字段拼起来,用一条真实的简化日志做演示:
{
"eventTime": "2025-06-15T08:30:21Z",
"eventName": "Decrypt",
"userIdentity": {
"type": "IAMUser",
"arn": "arn:aws:iam::123456789012:user/service-bot",
"userName": "service-bot"
},
"resources": [
{
"ARN": "arn:aws:kms:us-east-1:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab",
"type": "AWS::KMS::Key"
}
],
"sourceIPAddress": "10.0.1.50",
"userAgent": "aws-sdk-java/2.20.0",
"requestParameters": {
"keyId": "arn:aws:kms:us-east-1:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab",
"encryptionContext": {
"env": "production"
}
},
"responseElements": null
}
这条日志告诉我什么?
- 时间:08:30:21 UTC,下午的工作时间,正常
- 操作:Decrypt,常规使用
- 身份:service-bot,一个服务账号
- 资源:生产环境的主密钥
- 来源IP:内网IP,符合预期
- SDK版本:2.20.0,版本较新
- 加密上下文传了 production 标签
如果巡检脚本过一遍这些维度,全部绿灯,那就放行。一旦任何一项对不上——比如IP变成公网、SDK版本突然降级、加密上下文为空——直接拉起告警。
小技巧:在看日志的时候,别只盯着单个字段。我习惯把时间戳、操作类型、身份信息和资源标识四个字段放在一起看,形成一个「时间-谁-对什么-做了什么」的句子。举个例子:
「2025-06-15 08:30:21,service-bot 对 key/prod-master-key 执行了 Decrypt 操作。」
是不是一下子清晰多了?
嗯,日志格式这块,说到底就是个熟能生巧的过程。刚开始你可能需要对着表格一个个字段翻,但等巡检脚本跑起来,每天扫个几千条日志之后,你闭着眼都能看出哪条日志不对劲。
下一块要讲的就是如何把这些字段组织成巡检规则,让机器替你干活。不过那是后面的事了,先把日志格式吃透,基础牢了,后面才能盖起高楼。