目的随作者一起离开的绕过,正是活得比用处更久的那一类,而锁定策略收集它们的速度超过任何其他配置。写成“允许本地网络”的例外,是一条没人能辩护、也没人能退役的规则,因为它背后的需求已随添加它的人一起离开。这类策略之所以失败,是因为它们携带着理由已蒸发、风险却仍在的豁免。写清范围、失败行为和移除步骤的时机,就是你添加例外的那一刻——趁还有人记得为什么。

这是关于记录必须包含什么的决定,而不是一张待填的模板。下面四个字段,决定评审者一年后能否不开会就移除该规则。每一个之所以存在,都因为缺失它有可预见的代价。

为什么没有文档的绕过永远不会被退役

没有描述的绕过无法测试,因此无法安全移除。它在每次评审中都能幸存,因为删除看起来有风险,而保留看起来无害;每放过它一次,下一次也更容易放过。代价一直不可见,直到审计问起为什么某个私有网段被豁免,而那时答案只能是耸肩。

记录必须足够短,短到人们真的会在变更窗口里写下来。一行写流量,一行写它所服务的要求。

把范围写成流量

列出应用或目标网段、涉及的地址族、服务与端口,以及规则生效的网络环境,然后写明批准人和承载它的确切客户端或平台设置。“打印机”是一种意图;“TCP 631 到 192.168.1.50,仅家庭网络”才是可核验的范围。如果对“它住在哪里”的回答是“在 MDM 配置文件的某个地方”,记录就没写完。文件路径、配置文件名称或注册表键,胜过对设置可能在哪里的描述。

在平台支持按应用规则的地方,优先于地址段,因为只允许一个应用绕过隧道,比豁免整个私有子网更窄,而且设备换到新地址后它依然有效。Android 的 VpnService 指南描述了这种按应用的模型;桌面客户端通过各自的配置文件设置表达同样的思路。基于地址的豁免是平台提供不了更窄方案时的退路,所以它们更需要一条更锋利的范围说明。

四类例外,四种移除风险

例外并非同一类,移除它们的后果也不同。把两类例外挤在同一行,正是退役一台打印机会连连接能力一起退役的原因。

KindTypical exampleRemoval risk
Endpoint bootstrapreaching the gateway before the tunnel existshigh: nothing comes up without it
Captive portalhotel or airport sign-in pagemedium: only matters on untrusted networks
Local deviceprinter, casting target, test instrumentlow: one service at one address
Excluded applicationan app that must not use the tunnelmedium: depends on the app's own behaviour

即使实践中相互重叠,也要把 bootstrap、门户、设备和应用例外分写在不同的行上。私有网段豁免会悄悄放行该子网上的每一个邻居,而不是你本想够到的那一台设备;这正是可辩护的范围与只能指望的范围之间的差别。

隧道断开时,绕过会怎样

问三个问题并把答案写下来,因为它们决定锁定是否真实。隧道断开时例外是否仍然可用:对强制门户必须可用,否则永远没人能登录;对私有资源通常必须不可用,否则策略只是装饰。它适用于所有网络,还是只在预期环境中适用——限定在家庭子网的规则,在恰好使用同一网段的公共网络上表现完全不同。每个答案都会同时改变规则和记录,所以留下不答的问题,就是别人日后会答错的决定。

第三个问题是:当目标改变地址时会发生什么——基于域名和基于地址的豁免在这里分道扬镳。基于域名的规则取决于解析何时发生、客户端如何应用结果,因此它们可能在一次看似无关的变更之后悄悄不再匹配,而故障看起来像 VPN 坏了,而不是豁免过期了。

测试、再测试,并写下移除步骤

为允许的路径写一个无害的测试,再写一个邻近的拒绝用例:打印机页面能打开,同一子网上的文件共享打不开。这一对证明例外足够窄,也正是评审者无需理解原始请求就能重复的一对。然后设定复测触发条件,因为从不复测的例外会逐渐偏离它当初为之而写的需求,而这种偏离在出问题之前一直不可见。

最后,记录如何通过拥有它的组件移除该规则,并让机密留在记录之外。描述一个服务和一条路由从不需要私钥、密码或任何人的浏览历史,而一份简短且持续维护的清单,胜过一条比写它的人活得更久的临时规则。

相关文章