2017 年 1 月 31 日深夜,GitLab 的一位工程师敲了一条命令,要清空备用服务器上的一个数据库目录。一两秒后,他看清了自己在哪台机器上:主库,放着线上数据的那一台。等他把命令停下,约 300 GB 的数据只剩下 4.5 GB 左右。
本来还可以指望备份。GitLab 的事后复盘写道:「通常遇到这种情况,用一份最近的备份,应该能在比较短的时间里把数据库恢复过来。」工程师们去找备份。
每天的数据库导出,已经有一阵子什么也没导出来:它用的是一个跟新版数据库不兼容的旧工具。这个任务倒是会发失败通知邮件,可邮件被收件服务器退了,没人看到。这还只是他们找的第一种备份。按 GitLab 自己的记录,五种备份和复制手段都摆在那里,没有一种能可靠工作,有的根本就没配好。
一片片奶酪
英国心理学家詹姆斯·里森解释过为什么这种事一再发生。他 1987 年第一次画出一层层防线,几年后,一位澳大利亚的航空安全调查者给它配上了奶酪的比喻。他在 2000 年的《英国医学杂志》上写道,危险的系统靠一层层防线守着:有的是工程上的,比如警报、自动停机;有的是人,比如飞行员、外科医生;有的是规程。理想状态下,每一层都完好无缺。「可现实中,它们更像一片片瑞士奶酪,上面有很多洞。」
这些洞不是固定的,它们「不停地打开、合上、挪位置」。一片上有个洞,通常不碍事,因为下一片挡住了。事故要等好几层上的洞「一时间对齐」。
在 GitLab,单看每个洞都扛得住。导出坏了,有快照就行;没开快照,导出正常也行;目录删了,只要还有一样能用就行。那一晚,哪一样都不能用。
这张图自己也有个陷阱:白板上画了五片,不等于有五份互相独立的保护。几层防线要是共用同一个账号、同一个没测过的流程、同一个想当然,一个洞就能一下子穿透好几层。被问到为什么没开磁盘快照,GitLab 的工程师写道:「我们以为别的备份手段已经够了。」被问到为什么没定期测试备份:「因为没人负责。」
两种洞
里森把洞分成两种。一种是「当场失误」:在一线直接操作的人手滑、走神、犯错,比如在错的服务器上敲了命令。另一种是「潜伏条件」,他称之为系统里的「常驻病原体」,是设计者、建造者、写规程的人和管理层早就埋下的:一个没人测过的邮件校验,一份没人负责的备份。它们可以安静地待上好几个月,直到某个当场失误撞上来。
「当场失误就像蚊子,」他写道,「可以一只一只拍死,但它们还会不断飞来。」更好的办法是把滋生蚊子的沼泽排干。所以出了事,「要紧的不是谁犯了错,而是防线怎么失守、为什么失守」。
设想周五午饭高峰,一位服务员接了一单,客人是个对坚果过敏的孩子,她把这一点写在了单子上。厨房的打单机只打得出一行备注,过敏那句被截掉了一半。平时会把单子念出声的那位厨师,那天请了病假。甜点新加了一种装饰,没人把它补进过敏原清单。每一件都是小事。凑在一起,一盘果仁糖就端到了孩子面前。那位服务员什么都没做错。换一个服务员,打单机和过敏原清单照样是坏的。
用训练做成的那一片
AI 系统也靠一片片奶酪守着。2025 年,Anthropic 公开了一份报告,正好看到好几片同时在起作用。
据公司判断,一个由国家支持的中国黑客组织,用它的编程智能体 Claude Code 去攻击全球大约三十个机构。第一片是 Claude 本身,它「受过大量训练,避免有害行为」。攻击者穿过了这一片:他们把攻击拆成「一个个看起来无害的小任务」,还告诉 Claude,它是一家正规网络安全公司的员工,在做防御测试。这场行动在少数几个目标上得了手。
后面的一片挡住了。2025 年 9 月中旬,Anthropic 的监测发现了异常。接下来十天里,公司封禁了相关账号,通知了受影响的机构,并和有关部门合作。Anthropic 还注意到一点运气:Claude 有时会编造登录凭据,或者把公开信息说成偷到的机密,给攻击者添了乱。这是攻击里碰巧出现的一个洞,不是谁能指望的一片防线。
Anthropic 的应对,正是里森会预料到的那种:加更多、更厚的奶酪片。它扩大了监测范围,做了更好的分类器来标记恶意活动。
GitLab 的补救也是这个思路。它列出的后续工作里,有一套新的数据库恢复流程,还有给「数据持久性」指定一个负责人。备份要有人真的拿它恢复过一次,才算得上一片奶酪。