第二讲:审计日志的数据源——GitHub、GitLab、AWS Secrets Manager、HashiCorp Vault
讲完告警架构,咱们得聊聊数据从哪来。说白了,审计日志就是秘密管理系统的「黑匣子」。你想想看,没有日志,告警就是无源之水。我个人习惯把这四大数据源分成两类:DevOps 平台和秘密存储仓库。前者管谁在改代码、推PR,后者管谁在读、写、删秘密。
2.1 GitHub 审计日志
GitHub 是目前最流行的代码托管平台。它的审计日志分两层:组织级 Audit Log 和 企业级 Audit Log。组织级免费,企业级需要 Enterprise 计划。我刚开始接手安全运维时,就踩过一个坑——以为 GitHub 的审计日志会自动保留一年,结果发现免费版只保留 90 天。嗯,这里要注意:你至少得配置日志导出到 S3 或自定义存储。
GitHub 日志事件常用字段:
@timestamp— 事件发生时间actor— 谁执行的操作action— 操作动作(如secret_scanning.alert.created)repo— 仓库名称org— 组织名
告警场景举例:当 secret_scanning.alert.resolved 事件在短时间内被反复触发,可能是攻击者在测试你的告警响应机制。我个人遇到过一个人工智能训练项目,因为某个脚本不小心硬编码了 API ,GitHub 自动扫描发现后触发了 200 多次告警——后来我们加了告警聚合规则。
2.2 GitLab 审计日志
GitLab 的审计日志比 GitHub 更细粒度。它不仅能记录 Project、Group、Instance 三级事件,还能记录 Deploy Key、CI/CD Variables 的变更。我曾经在 CI 变量里发现了一个过期的 AWS Secret Key,排查后才知道是离职同事没清理。那之后我建议所有 CI 变量变更都要触发告警。
| 平台 | 日志保留期 | 关键事件类型 | 导出方式 |
|---|---|---|---|
| GitHub | 90 天(免费)/ 1年(企业) | secret_scanning.*、repo.* |
Webhook / API / S3 导出 |
| GitLab | 可配置(默认 1 年) | audit_events、ci_variable* |
HTTP Endpoint / 文件导出 |
| AWS Secrets Manager | 默认开启 CloudTrail | GetSecretValue、RotateSecret |
CloudTrail / EventBridge |
| HashiCorp Vault | 审计日志默认不开启 | secret.*、auth.* |
File / Syslog / Socket |
避坑指南:我曾经在 GitLab 的审计日志里发现 CI/CD 变量的值被明文记录在日志里——如果启用了 log_unsafe_events 参数,某些敏感信息可能会泄露。建议生产环境关闭这个参数,或者对日志做脱敏处理。
2.3 AWS Secrets Manager 审计日志
AWS Secrets Manager 本身不存储审计日志,它依赖 AWS CloudTrail。每次对秘密的 GetSecretValue、RotateSecret、DeleteSecret 操作都会被 CloudTrail 捕获。你想想看,如果某个 IAM 用户在不常出现的时间段调用了 GetSecretValue,那很可能就是被盗用的信号。
配置要点:
- 确保 CloudTrail 已经启用,并且 Data Events 勾选了
Secrets Manager。 - 建议用 EventBridge 规则直接触发 Lambda,实现实时告警。
- 日志格式是 JSON,注意解析
requestParameters.secretId和sourceIPAddress。
# CloudTrail 事件示例(简化)
{
"eventVersion": "1.08",
"userIdentity": {"arn": "arn:aws:iam::123456:user/bob"},
"eventTime": "2024-03-15T08:30:00Z",
"eventSource": "secretsmanager.amazonaws.com",
"eventName": "GetSecretValue",
"requestParameters": {"secretId": "arn:aws:secretsmanager:us-east-1:123456:secret:prod/db-pass"},
"sourceIPAddress": "203.0.113.42"
}
注意:CloudTrail 日志有 15 分钟左右的延迟,不能做到秒级告警。如果你的业务对实时性要求极高(比如秘密被读取后 30 秒内必须阻断),可以考虑配合 CloudWatch Events 的实时流(但会增加成本)。
2.4 HashiCorp Vault 审计日志
Vault 的审计日志默认是关闭的,这一点很多人不知道。你需要手动在 Vault 配置文件中启用 audit 后端,并且指定存储设备(文件、Syslog 或 Socket)。我建议用 File 后端,配合 Logstash 或 Fluentd 收集到 ELK。
关键配置示例:
# Vault 配置启用审计日志
path "audit/*" {
capabilities = ["create", "update"]
}
# CLI 启用文件审计
vault audit enable file file_path=/var/log/vault/audit.log log_raw=true
Vault 审计日志的字段结构:
time— 事件时间戳type— 事件类型(response、request)auth.accessor— 认证 摘要request.path— 操作的路径(如secret/data/prod/mysql)response.data— 返回的数据(注意脱敏)
实用技巧:Vault 的 log_raw=true 会把完整响应记录到日志里,包括秘密值。除非你确信日志存储是安全的,否则建议结合 hmac_accessor 和 hmac_data 选项做哈希脱敏。我曾经在一个 SOC 项目中看到有人忘了关 log_raw,结果审计人员直接看到了数据库密码——真是一身冷汗。
2.5 统一审计日志模型
不同平台的日志格式千差万别,但核心字段其实差不多。我把它们抽象成一个统一模型,方便后续写告警规则和自动化处置。
| 统一字段 | 对应各平台字段名 | 说明 |
|---|---|---|
event_time |
GitHub: @timestamp; GitLab: created_at; AWS: eventTime; Vault: time |
标准化为 ISO 8601 |
actor |
GitHub: actor.login; GitLab: user.username; AWS: userIdentity.arn; Vault: auth.accessor |
建议用 UID 或 ARN |
action |
GitHub: action; GitLab: action; AWS: eventName; Vault: type |
使用统一词表映射 |
resource |
GitHub: repo; GitLab: target.uri; AWS: requestParameters.secretId; Vault: request.path |
便于关联 |
source_ip |
GitHub: actor_ip; GitLab: ip_address; AWS: sourceIPAddress; Vault: request.remote_address |
用于地理位置分析 |
有了这个统一模型,后续写告警规则时就不必为每个平台单独解析了。我个人习惯在日志采集阶段就做一次「字段标准化」,后面所有告警引擎只认这套标准字段。
你想想看,四个数据源虽然协议各异,但只要在采集层统一字段名,后面写告警规则就只认这套模型。这招我在一个金融客户那里用过,他们原先每加一个数据源就要改告警代码,后来改成这个架构,新增数据源只需要写一个采集适配器——爽快多了。
避坑指南:我建议你别把所有数据源的原始日志直接喂给告警引擎,那样规则会变得无比臃肿。先做字段标准化,再做一个事件归类映射(比如把 secret_scanning.alert.created 和 GetSecretValue 都映射为 SECRET_READ)。这样后续的告警阈值和处置策略才能通用。