IP 路由匹配的是地址前缀,内核直接按它执行,不再追问。基于域名的 VPN 规则匹配的是名字,这就意味着协议栈里必须有东西判断这个名字当下对应哪些地址,并让这个判断保持最新。两者机制不同,失效方式也不同,厂商却常用同一个词来指代。在功能清单里比高下没有意义;该比的是答案变化时会发生什么。

真正有用的区分,是规则到底会不会做解析。

每种规则究竟匹配什么

前缀规则匹配路由表中的目的地址。没有解析,没有过期,每个数据包都精确命中。域名规则匹配的是应用对某个名字的请求,而RFC 1034把名字定义为标签树,而不是地址。有些产品只解析一次名字,把结果地址装成路由,这条规则就变成了一条附带刷新定时器的 IP 规则。

调试之前先弄清自己用的是哪一种,因为两种情况的故障表现完全不同。

域名规则位于协议栈的哪一层

如果产品用本地代理实现域名规则,流量就必须先到达那个代理,而绕开系统代理的应用会完全跳过这条规则。如果靠解析名字再添加路由来实现,地址只在最近一次刷新前是新的。如果它挂接在解析器上,DNS 行为就成了路由策略的一部分,一个兜底解析器可以悄无声息地把它作废。

看厂商的实现模型,而不是设置界面的标签。两个都叫“分流开关”的客户端,可能在做的却是三件不同的事。

比较哪里会坏

有三处坏法各不相同。地址漂移:CDN 主机名几分钟内就能解析到另一组地址,照抄的清单很快就过时。子域名范围:针对 example.com 的规则未必覆盖 api.example.com,文档通常会写明是哪种。解析失败:解析器失灵时,会解析的客户端可能退回去把流量走隧道,也可能直接放行。

只有第二处是配置问题。另外两处是设计问题,取决于产品愿意猜多少。

BehaviourPrefix ruleDomain rule
Match basisdestination addressrequested name or resolved addresses
Stalenessnonedepends on refresh policy
Subdomain scopenot applicableproduct-defined
Resolver outageunaffectedproduct-defined fallback
Where to debugrouting tableclient log plus resolver state

什么时候前缀是更好的答案

对稳定的私有子网来说,显式前缀更清楚、更快,也更容易审计。它还能扛住解析器故障,因为根本不需要解析。只有当服务托管在外部、地址会轮换,或者你确实无法枚举目的地址集合时,才该动用域名规则。不要仅仅因为你刚好知道主机名就去用它。

猜出来的静态清单是两头不讨好:看起来像有人维护,可等到服务商新增一台主机的那天,它会悄悄漏掉流量。

用一次全新请求来验证

在一次正常重连之后用冷请求测试,因为缓存页面可能根本不会碰到这条规则。先解析名字,再看连接实际走了哪里。dig +short app.example.com给出当前的地址集合,客户端的连接列表会告诉你流量走的是哪个网卡。

按产品文档给出的刷新间隔再测一次。如果地址集合已经变了,规则却没有跟上,你就找到了真实行为。

解析器策略也要单独看待。域名规则需要正确的名字数据,但它本身并不决定由哪个解析器来回答查询。

相关文章