跳到主要内容
门拦住你自己的那天,才算真装上了

门拦住你自己的那天,才算真装上了

画唠
画唠

· 阅读约 5 分钟

先撂一句:自动化安全门禁这事儿被讲玄了。讲的人张口就是“零信任”“安全左移”,好像管道一挂就自动安全。没人告诉你的是——门真装上之后,第一个被拦在门外的很可能是你自己,而且多半挑最不该拦的时候。

最近看到一个案例,把这事拆得特别干净。Siemens 一个管 Kubernetes 的工程师,家里跑着裸金属集群,之前还写过个叫 NEMESIS 的紫队工具专门打自己的基础设施——进攻有自动化,防御全靠人。于是他补了一条完全无人介入的 GitOps 安全管道,挂在 ArgoCD 的 PreSync 钩子上:同步前跑一个 Job,渲染 Helm chart,过三道扫描。Job 挂了,同步就中止。

画张图,长这样:

   git push ──► ArgoCD ──► PreSync Job
                              ├─ kube-radar(RBAC 风险评分)
                              ├─ NEMESIS 静态分析(Trivy + CVE 检查)
                              └─ 发 Slack
                              │
                    Job 成功 ──► 同步继续
                    Job 失败 ──► 同步中止 ✋

三道门各有各的脾气。kube-radar 见到通配符直接拦,pods/exec 这类权限标记成要人审;NEMESIS 拉 CVE 超过 7.0 的直接判死刑;还有个四百行 Go 写的 kyverno-lite 准入 webhook,管四条规矩——不许 root 跑容器、不许 latest 标签、不许 RBAC 三件套全通配、每个部署必须设 resources.requests。failurePolicy 还是 Fail,webhook 挂了集群就拒收资源。听着挺凶。

然后就是名场面。月末一个星期五,下午 4:47,他要部署一个计费服务的时区补丁——一行 Python 改动。PreSync 挂了。部署不了。

为什么?前一天晚上合进去的 kube-radar v0.3 新规则,把 pods/exec 定成了严重问题,而仓库里一个叫 vehiclemetrics-billing-sa.yaml 的文件,带着这个权限躺了好几个星期。一行 Python 的事,触发了全量 RBAC 检查。

等等等等,先别急着笑“这规则也太糙了”。这事真正有意思的在后面:他站在那个岔路口——手动绕过安全门,还是不绕——他没绕。花八分钟写了个最小权限的 Role 替掉过度授权,然后正常部署。

就这八分钟,我觉得比整套管道都值钱。

为什么。大多数安全自动化的故事讲到“装上了”就完了,没人讲那个最难受的时刻。门禁这玩意儿,打个比方:它是个守门的保安,但保安不看脸色、不看时间、不知道现在是星期五下午快下班——只看规则。这个比喻有个地方漏风,我得老实标出来:真人保安被说服几次就会松,规则不会松,但规则会被——前一天晚上那条“把 pods/exec 定为严重”的合并,就是有人趁保安不注意塞了张新告示。所以最危险的不是门本身,是“改门的人”和“被门拦的人”不在同一个时刻做决定。

他后来的处理也值得画开。周末把自家仓库翻了一遍,翻出四个严重问题:debug 命名空间里 ConfigMaps 的 verbs 通配符、monitoring 的 ServiceAccount 绑着 cluster-admin、备份 Job 用 root 跑、traefik 的 RBAC 在三个资源上通配。注意——这四个全是他自己的。装门之前它们就在那儿,“4 个已知 + 不知道多少未知”;装门之后归零。

然后他干了两件很工程的事,不是很“安全”的事。

一件是 @security-override 标签。只有 security-admins 团队(就他一个人)能加,带标签的 PR 照样扫描但只警告不阻断,所有覆盖操作进专门的 Slack 频道和一个只写 S3 桶。另一件是把 webhook 的 failurePolicy 从 Fail 改成 Ignore,但补了个逻辑:webhook 摸不到的时候,ArgoCD 把 Application 标成 Unknown、暂停自动同步。

画出来:

   之前:webhook 挂 ──► 整个集群拒收(安全了,但也不可用了)
   之后:webhook 挂 ──► Application = Unknown ──► 暂停自动同步
         webhook 活 ──► 正常强制执行

健康时强制,故障时可用。这才是成熟的安全观——不是把门焊死,是给门配一把有记录、范围受限、别人拿不走的钥匙。他总结的教训里我最认同两条:不要周四晚上发布改变“严重”定义的规则;门应该扫变更的 diff,不是整个渲染后的清单树。那次星期五事故的直接技术原因就是后者——一行 Python 触发全量 RBAC 检查,等于每次进门都全身搜查,哪怕你只是来还个充电器。评论区还有人建议把策略生效拆成“审计→基线→强制”三段走、diff 按渲染后的能力变更算,思路是对的。

数字我也信,因为它们不漂亮得过分:PR 安全审查从 45 分钟降到 3 分钟,每月约 3 个 CVE 归零。三周后没有凌晨三点的告警;一个客户请的渗透测试员花了两天提权,最后只在 staging 里摸到一个过度授权的 Role。

回到我最想说的那个点。这件事最酷的不是工具链——kube-radar 也好 kyverno-lite 也好,四百行 Go 而已,任何一个懂 K8s 的周末都写得出来。酷的是下午 4:47 那个岔路口。自动化安全门真正的考验从来不是它拦住了多少坏东西,而是它拦住你自己的时候,你是拆门还是修问题。他选了修问题,八分钟。那一刻门才算真的装上了——之前的它只是个 CI 配置。

反过来想也成立:如果你装的安全门从来没拦过自己人,要么你的仓库干净得不像话,要么那门根本没在看。

下期想画开哪个?我清单上有个新候选:准入控制链里 mutating 和 validating 的执行顺序——好几次我以为我懂了,动手一试发现不对。先立个怀疑,试试再说。

画唠
画唠

把被讲玄的概念用图 + 比喻 + 动手实验拆到咔哒扣明白,错的也保留。

查看主页 →