VPN 一连接,DNS64 答覆为什么就变了?
DNS64 答覆编码的是一种转换假设。检查是哪个解析器作答、该前缀是否被路由,以及你的路径上是否坐着转换器。
DNS64 答覆描述的是网络安排,而不是服务器的属性。解析器用 IPv4 地址合成出 IPv6 地址,结果只在该前缀末端有转换器的地方才有效。把 VPN 接进路径,这种安排可能维持、改变或不再成立,取决于三个条件。
这三个条件是:作答的解析器、你的设备到合成前缀的路由,以及该路由上是否有任何东西执行转换。每一项都可观察,正因如此故障才可诊断。
合成出来的 AAAA 记录究竟指向什么
DNS64 解析器回答一个只有 IPv4 的名称的 AAAA 查询时,会把 IPv4 地址嵌入它被配置使用的某个前缀之中,而这项工作公认的前缀是 RFC 6147 所述的 64:ff9b::/96。对应用来说,这条记录看上去和任何其他 AAAA 记录一样,而这正是要点:只有 IPv6 的客户端可以尝试连接,却不知道目的地从来没有过 IPv6。随后这条连接取决于路径某处执行两族之间转换的 NAT64 功能。没有那个转换器,合成地址就是一个看起来很合理、却哪儿也到不了的终点。
因此这条记录同时编码了两件事:原始 IPv4 地址,以及转换器可达这一假设。只有前者在答覆本身中可见。
三个条件决定它是否仍然有效
第一个条件是谁生成了这条记录,因为未配置 DNS64 的解析器对该名称不返回任何东西,应用会以另一种方式失败。第二个条件是设备到合成前缀是否有路由,因为答覆可能有效,而通往它的路径缺失。第三个条件是拥有该前缀的转换器是否在你将使用的路径上,因为把 64:ff9b::/96 运往别处的隧道只会到达另一个功能,或什么也到不了。这三条在隧道之前可以成立,之后却失败,症状于是看起来像一次突然的退化。
按这个顺序检查。答覆缺失与路由缺失在浏览器里看起来一模一样,在解析器日志里却完全不同。
解析器一变,答覆就变
VPN 客户端常常推送自己的解析器,或者干脆接管整条查询路径,而这个解析器可能什么也不合成。于是只有 IPv4 的名称查询不返回 AAAA 记录,只有 IPv6 的客户端把它体验为一个够不着的名称。反过来也会发生:真正会合成的解析器可能给你一个隧道路径并不承载的前缀。
缓存让这件事更难看清。在办公室网络上取得的合成记录可能比产生它的上下文活得更久,于是客户端继续连接一个转换器已不可达的地址。要看现在作答的解析器,而不是条目保存时作答的那个。不记录新旧答覆就清空缓存,会毁掉你需要的证据。
分别测试查询与路径
在牵涉应用之前直接查询该名称,并记下是哪台服务器作答。下面的命令显示 AAAA 记录、正在使用的解析器,以及通往合成前缀的路由是否存在。先在隧道关闭时运行,再在隧道开启时运行一次。
dig AAAA ipv4only.example.com +short
dig AAAA ipv4only.example.com | grep -E '^;; SERVER'
ip -6 route get 64:ff9b::c000:0216
curl -6 -sS -o /dev/null -w '%{http_code} %{time_connect}\n' --max-time 8 http://ipv4only.example.com/
把结果当作一条链来读。缺少 AAAA 记录意味着面前的解析器不合成,因此只有 IPv6 的路径对该名称不会生效,客户端做什么都一样。记录存在但没有路由,意味着当前路径不承载该前缀,这是路由决策,不是解析器故障。路由存在而请求仍然失败,指向转换器本身,那属于另一个所有者。
在每个结果旁边记录解析器、网络上下文和地址族。正是这条记录,让下一次比较能把解析器的变化与路由的变化分开。