【背景】
做安全加固这几年,见过最典型的线上事故不是「漏洞被打了」,而是「安全组件挂了,默认动作选错了」:
- 一个电商网关,鉴权 token 校验服务(独立微服务)挂了 40 分钟。因为网关里写的是
try { validate(token) } catch { return true },结果那 40 分钟所有内部接口都是无鉴权直连——事后复盘,恰好有个内部爬虫在这期间把 3 张用户表拉了个遍。 - 一个风控引擎挂了 12 分钟,fail-open 放行,结果一波羊毛党薅了 80 万积分,事后追不回来。
- 一个 K8s admission controller 挂了,fail-close,所有 Pod 创建全部卡住,业务 40 分钟没上新版本,值班同学骂了一整晚。
三件事的根因都不是 bug,都是**「安全/策略组件故障时的默认动作」没被当作一个显式决策项**。多数团队是"写在代码里的一句 try-catch",从来没被评审、没被演练、没被写入故障预案。
【常见分歧:四种典型立场】
- 可用性优先派(fail-open 默认):业务不能停,安全是"事后补",先放行、事后再审计。常见于电商大促、支付前置链路。
- 安全优先派(fail-close 默认):宁可错杀不可放过,故障 = 拒绝,业务侧自己去做降级。常见于金融、政务、内部核心系统。
- 分级派:核心链路 fail-close,边缘链路 fail-open,按"资源敏感度 × 业务影响"打分。理论最优雅,落地最难——谁来定这个分?多久重评一次?
- 白名单派:默认 fail-close,但允许业务侧显式声明某条路径可以 fail-open,走审批 + 审计日志 + 时间窗口(比如"最多 fail-open 5 分钟,超时自动切 close")。
【我的倾向与理由】
我的默认立场是 fail-close + 显式白名单例外,理由有三:
- fail-open 是异常状态,必须走审批通道——代码里的
catch { return true }等于把安全策略的裁决权交给了"网络抖动",这是不可接受的。让"放行"从代码默认值变成"配置项 + 审批 + 时限",责任就落到人了。 - fail-open 必须有时限和自动回收:一旦进入 fail-open 状态,计时器启动(比如 60s / 5min),到期未恢复自动切回 close,并触发 P1 告警。无限 fail-open = 等于没做安全。
- fail-close 的代价要提前演练:很多团队 fail-close 看着对,但没演练过"鉴权挂了 5 分钟,业务侧到底能不能降级、降级到什么粒度、谁来批准降级"。fail-close 不是"拒绝就完事",它要求业务侧有配套的降级预案,否则 fail-close 只是把"安全事件"变成"业务事故"。
一句话:fail-open 是例外,fail-close 是默认;例外必须有时限、有审批、有回收。
【想听大家拍砖的几个具体问题】
- 你们线上有没有显式声明的 fail-open 白名单?走什么审批流程?时限怎么定?
- 故障时 fail-open 的窗口多长?由谁关闭?关不关得回来?
- 有没有「fail-open 后没被发现,事后才复盘」的真实事故?根因是缺监控、缺告警、还是缺审计?
- 你们怎么给"资源敏感度 × 业务影响"打分?有没有可复用的评分模型?
- admission controller / 限流器 / 风控引擎 / 鉴权网关,这四类组件你们的默认动作分别是什么?有没有统一规范?
欢迎贴真实案例(脱敏即可),尤其是"我选错了 fail-open,后来怎么样了"这种复盘帖——这类内容比"我选对了"更有价值。
0赞
0收藏
0楼层