分隧道如何决定哪些流量走 VPN
分隧道是一组路由与绑定决策,而不是一个可以打开的开关。了解按应用规则、前缀、DNS 与安全开关如何相互作用。
分隧道是一种以规则集合表达的路由策略,而客户端只是安装这些规则的东西。分离发生在两处:为每个数据包选择路径的匹配规则,以及无论路由表怎么说都把应用固定在一个接口上的绑定。客户端依赖哪种机制,解释了人们报告的大多数意外。
能在一行里说清的策略是可测试的。被描述为浏览更快的那种策略则不是,而且当请求走错方向时,它不会告诉你该改哪条规则。
客户端安装规则,内核做出选择
隧道建立时,客户端会把路由和常常还有策略规则加入你其他接口所用的同一张表。随后每个数据包都会到达一次查找,将目的地与每个候选前缀比较并保留最具体的匹配,而优先级则解决指向不同表的规则之间的平局。那次查找中的任何东西都不知道数据包来自浏览器标签页而不是备份任务。获胜的规则才是设定路径的规则,你可以在改动前后读到它。
这就是分隧道可能显得随意的原因。同一应用中的两个目的地可能走不同的路,仅仅因为一个前缀比另一个更窄。
每个平台都有同样的选择,只是名称不同。Windows 把决策推进它的筛选平台,Android 通过其 VPN 服务公开按应用的允许列表,macOS 则把隧道附着到一个仍然服从路由表的设备上。 Microsoft 的路由说明值得为 Windows 的情形读一读,而为某一个平台写的指南很少能原样搬到另一个平台。
按应用绑定与目的前缀是不同的工具
目的策略问数据包要去哪里,并查阅路由表或策略规则。按应用策略问哪个程序打开了套接字,平台会把该程序固定在隧道接口上,即使更具体的路由指向别处。第二种更强,因为它能经受表的变动,但它只覆盖平台能够归属的进程。辅助进程、内嵌浏览器或自己打开连接的服务,可能不会继承你假设的绑定。
两种方法都离不开帮助,无法应对基于名称的策略。大站点的地址会在内容网络之间轮换,所以把一个主机名钉在几个前缀上,会产生一条悄悄停止匹配的规则。必须跟随名称的策略需要能感知解析器的组件,而不是静态路由。
DNS 与安全开关遵循自己的规则
名称解析是与数据包路由分开的决策,分隧道通常想要两个解析器:公司的一个用于内部名称,本地的一个用于其他一切。客户端可以安装按接口的 DNS 设置,把查询交给中间解析器,或让系统默认值保持不变。自带加密解析器的浏览器会绕过这三种安排。不要假设解析器遵循了路由,去测试一次查询。
安全开关在上面加了一层过滤器,而那个过滤器并不总能区分有意的排除与意外的泄漏。有些客户端会封锁隧道之外的一切,另一些则允许策略声明的排除项,所以在依赖其中任何一种之前,先读一读你的客户端实现的是哪种行为。
从两侧检查分离
分别测试被包含的路径和被排除的路径,并依据接口名称而不是公网地址来判断结果。这些命令假定 Linux 主机上隧道设备已经启动。把 203.0.113.10 换成你的策略走向内的目的地,把 198.51.100.25 换成它走向外的目的地。
ip route get 203.0.113.10
ip route get 198.51.100.25
resolvectl query intranet.example.com
curl -s --interface tun0 https://example.com -o /dev/null -w '%{http_code}\n'
把前两个答案放在一起读,因为每一个中命名的接口都显示了分离是否把该目的地放在了隧道上。解析器查询显示哪个服务器回答了内部名称,最后一条命令则证明隧道设备至少能承载一个请求。第一行成功而第二行失败,意味着策略正完全按吩咐行事。
在重新连接之后和网络变化之后重复这一组。租约续期与接口更替正是分离开始不符合其设计意图的地方,而每次运行保存的输出让偏移一目了然。