第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,除非你对接的老设备只能输出这种格式。

PKI审计日志结构框架 审计日志条目 头信息 事件体 尾部元数据 事件体详细子字段 操作主题 操作对象 操作动作 操作结果 常见日志格式 Syslog(RFC 3164/5424) JSON KV Key-Value 图注:日志条目自上而下分解为头信息、事件体、尾部元数据;事件体包含四个维度;最终序列化为三种常见格式。

最后说一句选型上的个人建议:能用JSON就别用Syslog,能用Syslog就别用KV。JSON的灵活性在运维审计中太重要了——特别是当你需要加字段的时候,JSON只需在扩展区随便加,而Syslog的结构化数据部分写起来简直反人类。我记得有一次客户要求记录证书模板的版本号,JSON那边加一行就完事,Syslog那边改了两个小时的解析脚本。