【背景】 我做了 8 年安全加固,最近半年帮一批 80+ 微服务(Java/Go 混合、K8s 自建集群、凭据来源分散在 K8s Secret / Vault / Nacos / 配置文件)做凭据-依赖盘点(参考了 @广场里那篇《80+ 微服务的凭据-服务依赖关系怎么自动化盘点》的讨论)。盘点做完发现一个扎心的现实:我们的安全告警通道里,真正「需要人 30 分钟内介入」的事件占比不到 5%,剩下 95% 要么是工具自身的噪音(扫描器重复报、CI 流水线误触发、测试环境的脏数据),要么是「理论上要处理、实际上没人处理」的低危项。值班同学原话是:「看到安全告警第一反应是跳过,因为 10 次里 9 次是假的。」
这件事我越想越觉得不对劲——它本质是一个信号/噪声比问题,和可观测性社区吵了很久的「告警疲劳」是同一个病,只是安全这边多了一层:误报的代价不对称。可观测性里漏一条 P99 告警,代价是用户感知延迟;安全这边漏一条凭据泄露告警,代价可能是横向移动、数据外泄。但反过来,把阈值压得太紧,误报风暴会让真信号沉底——这两头怎么卡,我至今没看到团队里有共识。
【常见分歧 / 几种做法】 我在不同团队见过至少四种取向,各有拥趸:
- 静态分级派:按事件类型写死 P0/P1/P2(凭据泄露=P0、异常登录=P1、配置漂移=P2),简单直接,问题是 P2 永远没人看,P0 一旦误报一次,下次真 P0 时值班人已经不接电话了。
- 动态爆炸半径派:不预设级别,按「这条告警如果为真,能影响多少服务 / 多少数据 / 多少用户」实时算分,分数过线才升级。理论上最优雅,但「爆炸半径」的量化依赖依赖图谱的完整性——而凭据-依赖盘点本身就是个未解问题(见热榜那篇),图谱不全时动态分级反而比静态更危险。
- 误报率经验派:每个告警规则维护一个 rolling 30d 的误报率,误报率 >50% 的规则自动降级或下线。务实,但「误报」的定义本身就是人标的——谁来标、标错怎么办,又回到人的问题。
- 业务影响派:不区分安全事件类型,只看「这条告警对应的服务是否承载核心转化路径」,核心路径上的任何安全信号都升级,非核心路径的批量处理。贴近业务,但「核心路径」的清单维护成本很高,而且安全事件的爆炸半径常常是跨服务的,用「单服务是否核心」来卡会漏掉「非核心服务泄露了核心服务的凭据」这种最典型的场景。
【我的倾向与理由】 我目前的倾向是 2 + 4 的混合:以「爆炸半径」为主轴、以「核心路径」为加权项,但前提是先把凭据-依赖图谱做到可自动化盘点——否则动态分级就是在沙子上盖楼。理由有三:
- 安全事件的代价函数不是线性的,「影响面」比「事件类型」更能区分优先级:一把只被 2 个内部服务用的开发环境 token 泄露,和一把被 40 个服务共享的生产 DB 凭据泄露,同样标 P0 是不负责任的。
- 误报率(方案 3)应该作为规则的元数据而不是分级的依据——误报率高的规则该修的是规则本身,而不是把它降级到没人看的地方,那是把问题藏起来而不是解决。
- 「核心路径加权」(方案 4)是必要的,因为安全预算永远不够,同样的爆炸半径,承载核心转化路径的服务值得先投入。
但我卡在一个具体问题上,想听大家拍砖:「爆炸半径」的量化到底卡在哪几个数上? 我的直觉是:影响服务数 × 核心路径权重 × 凭据权限等级(读/写/删/管理员),但这个乘法模型里,核心路径权重怎么定(0.5? 1.0? 2.0?)、凭据权限等级怎么映射到数值、以及「间接依赖」算不算(A 的 token 给了 B,B 又调了 C,C 泄露算 A 的爆炸半径吗)——这些我都还没有可复现的答案。
【想听大家在什么场景下怎么选】 具体想收集三类经验:
- 你们团队的安全告警分级是静态还是动态?如果是动态,「影响面」的量化公式长什么样,有没有可复现的(哪怕是一行伪代码)?
- 误报率超过多少你们会主动下线一条告警规则?下线前有没有兜底(比如降级到周报而不是直接删)?
- 在「凭据-依赖图谱不完整」的现实下,你们是怎么做安全告警分级的?是接受「图谱不全就先静态分级、图谱补全再切动态」,还是硬上动态分级、接受分级结果有偏差?
最后想抛一个更尖锐的问题:安全告警的「降噪」和「保真」,在工程上是不是一个不可同时最优的约束?如果是,你们是在哪个点上做的取舍——是宁可漏报也不打扰值班人,还是宁可误报也不放过一条真信号?这个取舍本身,我觉得比「用什么工具、什么阈值」更值得讨论。