两个需求常常被写成一句话,却在完全不同的地方实现。本网站只能通过 VPN 访问,说的是准入,天然属于服务前方的网络。本 iPhone 绝不能直接联系该域名,说的是设备,只有受管客户端策略才能表达。打开配置文件编辑器之前,先判断你真正面对的是哪一种。

两条听起来一样的需求

以示例主机 records.corp.example 为例。准入场景下,你只把它发布到 VPN 后方的地址,于是手机在蜂窝网络上的直连尝试会在网络层失败,而同一请求经隧道则能成功,并且仍然需要真实的账户登录。设备场景下,手机可以访问公网,主机对任何人都会解析并应答,唯一能拦住尝试的地方就是设备本身。服务无法对从未到达它的请求执行任何规则。

误读需求,会体现为一种具体的部署。记录仍然是公开的,运维方以为 VPN 是强制的,而对蜂窝尝试的审计显示请求从未进入隧道。日志里看不出任何故障,因为根本没有东西被拦截。

照字面理解评估动作

按需机制有两层彼此不同的动作,把它们混为一谈正是这里大部分混乱的来源。外层规则动作决定规则命中时隧道如何变化,连接评估动作则决定评估规则内部的主机名匹配如何处理。Apple 的 Never Connect 参考文档只描述了第二层。

LayerActionWhat it controls
Outer ruleconnectBring the tunnel up when the rule matches
Outer ruledisconnectTear the tunnel down when the rule matches
Outer ruleevaluateConnectionRun a hostname evaluation instead of acting directly
Outer ruleignoreLeave the current tunnel state alone
Connection evaluationconnectIfNeededStart the tunnel when the hostname cannot be resolved
Connection evaluationneverConnectDo not start the tunnel for that match

neverConnect 是最常被误读的取值,因为名字听起来像是封锁。它控制的是对匹配主机名是否启动隧道,而不是手机访问某个名称的权限,所以 Never Connect 条目并不是域名封锁。在设计文档里这样标注,就会让一次部署带着它实际上并不具备的强制边界获得批准。

你拥有服务时,就在边界上强制

限制准入意味着只在 VPN 路径能够到达的地方发布名称,然后验证预期路径可用、另一条路径不可用。覆盖每一条已发布的记录、如果你发布就覆盖两类地址族,以及应用使用的任何中间名或备用名。一条仍指向公网负载均衡器的旧 CNAME,会让直连路径继续存活,主记录整理得再干净也没用。

这保护的是服务而不是设备。它不会阻止手机发出 DNS 查询,也不会阻止应用去尝试。如果这些尝试可以接受,边界强制就是更便宜、更持久的选择,因为它对每个客户端都成立,而不只是你配置过的那些。它也能扛住从未注册过的手机。

当手机连尝试都不该有时,你需要受管策略

要阻止尝试,需要一项受支持的强制策略,覆盖连接前的应用或目标、隧道故障期间以及网络切换之后。请 VPN 或设备管理供应商说明该策略的名称、是否需要组织级管理,以及它还会影响什么。按应用划分的隧道加一条按需规则并不是一回事,主屏幕上的连接快捷方式也不是。

通过关闭隧道并观察请求是否外发,来测试失败场景。如果外发了,你记录的边界就不是你部署的边界。

用三个问题来决定

第一,你控制的是服务还是只有手机?第二,设备是否可以为其他一切合法使用公网?第三,手机是否受管,由谁管理?拥有服务加上受管设备群,意味着两层都可用;只拥有手机,则客户端策略是唯一选项,而且它必须得到支持。

在碰配置文件之前先回答这三个问题。此后配置就不再是对一个名为 Never 的复选框含义的猜测。

相关文章