第2章 审计日志的基本结构
审计日志看着密密麻麻,其实拆开来看就那么几块东西。我刚开始接触PKI日志时,也被满屏的时间戳和数字吓到过。后来我习惯先把一条日志拆成「头、身、尾」三个部分,一下子就清爽了。
2.1 日志条目组成
一条完整的PKI审计日志,说白了就三个层次:
- 外围头信息:谁产生的?什么时间?什么级别?——这部分通常由日志收集系统或syslog自动打上。
- 核心事件体:发生了什么事?涉及哪个证书?哪个用户?操作结果如何?——这是审计人员最关心的部分。
- 尾部元数据:消息ID、签名、校验值等。用于防篡改和链路追踪。
我曾在某个政务CA的日志里见过一种「四段式」结构,他们把事件体又拆成了「操作主题、操作对象、操作动作、操作结果」。嗯,这样设计确实方便写过滤规则。
避坑提醒:千万别把时间戳字段放到事件体内部去定义,那样解析器很难统一处理。时间戳就应该放在头信息位置,而且最好用UTC + 时区偏移的整数形式。
2.2 核心字段定义
不管日志格式怎么变,下面这几个字段几乎是标配。我整理了份表格,你写解析器或者做合规审计时可以直接拿来对照。
| 字段名 | 英文标识 | 类型 | 说明与常见值 |
|---|---|---|---|
| 时间戳 | timestamp | 整数/字符串 | Unix毫秒时间戳或ISO 8601格式,建议统一为UTC |
| 日志级别 | severity | 枚举 | DEBUG, INFO, WARNING, ERROR, CRITICAL |
| 事件类型 | eventType | 字符串 | 如 CertificateIssuance, Revocation, KeyGeneration, AccessDenied |
| 操作者标识 | actor | 字符串 | 管理员DN或系统服务账号,例如 CN=Admin,OU=CA,O=MyOrg |
| 对象标识 | object | 字符串 | 被操作证书序列号、CRL编号或密钥ID |
| 结果码 | result | 整数/枚举 | 0=成功,非0=失败,失败码会对应特定错误类型 |
| 消息体 | message | 文本 | 可读描述,有时也包含调试用的内部参数 |
| 额外字段 | extensions | JSON/KeyValue | 具体CA实现特有的扩展信息,如策略OID、加密算法 |
我的习惯:在做日志字段映射时,我会把eventType作为一个独立索引字段。为什么?因为90%的查询都是「查某类事件」,把这个字段单独拎出来,查询速度能快一个数量级。
2.3 常见日志格式
业内主要有两种流派:结构化格式和半结构化格式。我两种都维护过,给你说说实战感受。
2.3.1 Syslog(RFC 3164 / RFC 5424)
老牌日志协议,很多硬件HSM和老CA设备默认走它。格式长这样:
<14>1 2025-03-10T08:12:33.456Z ca01.example.com CAEngine 1234 - [meta eventType="CertificateIssuance"] CN=admin,O=Org issued cert serial=0xAB12CD34 result=0
你仔细看,尖括号里是优先级(facility×8 + severity),后面依次是版本、时间戳、主机名、应用名、进程ID、消息ID、结构化数据(方括号部分),最后是自由文本。我当年踩过一个坑:结构化数据部分如果包含空格或等号没转义,解析就会乱掉。所以一定要用严格的正则或专用解析库。
2.3.2 JSON格式
新式PKI产品几乎都用JSON,比如EJBCA、CloudHSM等。可读性好,直接就能喂给ELK或Splunk。示例:
{
"timestamp": 1741594353.456,
"severity": "INFO",
"eventType": "CertificateRevocation",
"actor": "CN=RevocationBot,OU=Automation,O=MyOrg",
"object": "0xFEEDBE01",
"result": 0,
"message": "Certificate 0xFEEDBE01 revoked due to key compromise",
"extensions": {
"certProfile": "serverAuth",
"revocationReason": "keyCompromise"
}
}
你看,JSON把字段名固定下来,解析器写起来特别稳。我曾经帮客户从Syslog迁移到JSON,同样的查询,后台处理时间从平均200ms降到了30ms——因为JSON不需要做模式匹配,直接点字段就行了。
重要提醒:不是所有JSON日志都严格遵循同一个Schema。有些厂商会在extensions里塞乱七八糟的key,你写解析器的时候一定要容忍未知字段,不能因为多了一个key就整个日志拒收。我见过有人因为这个丢过审计记录。
2.3.3 KV(Key-Value)对格式
Apache风格或自定义文本,在轻量级场景下还在用。比如:
timestamp=1741594353|severity=WARNING|eventType=ExpiringCert|cn=server01.example.com|daysLeft=7
KV格式看起来简单,但字段顺序不能保证,而且值里如果带竖线或等号一定要转义。我个人不推荐新项目用KV,除非你对接的老设备只能输出这种格式。
最后说一句选型上的个人建议:能用JSON就别用Syslog,能用Syslog就别用KV。JSON的灵活性在运维审计中太重要了——特别是当你需要加字段的时候,JSON只需在扩展区随便加,而Syslog的结构化数据部分写起来简直反人类。我记得有一次客户要求记录证书模板的版本号,JSON那边加一行就完事,Syslog那边改了两个小时的解析脚本。