在终端模拟器里输入files什么都不会返回;输入files.corp.example同一个服务器却立刻应答。VPN 凭据没有任何改动,私有 DNS 服务器也从未出过故障。在 Android 上,短标签与完整名字在解析器内部走的是两条不同的路径,而其中一条取决于隧道所有者必须提供的设置。你面前的判断不是改哪台 DNS 服务器,而是谁在管理应用实际使用的那个网络。

搜索域不是地址。它是解析器在放弃之前追加到裸标签后面的一串后缀。

搜索后缀和 DNS 服务器是两个不同的字段

解析器地址告诉 Android 去哪里问;搜索后缀告诉它,当你只给出最左边的标签时该问什么。两者住在同一个网络对象上,各自都可能单独缺失。

正是这种彼此独立,解释了完整主机名为什么能用。完全限定名不需要后缀,因为它本身就是发往服务器的那串字符。

Android 通过LinkProperties把这个拆分暴露出来。DNS 服务器列表和域搜索列表挂在同一个对象上,前者填满时后者经常是空的。有解析器却没有域的网络,是后缀从未被应用过的网络,而不是拒绝了短名的服务器。

改动任何东西之前,先读实际生效的网络

Wi-Fi、蜂窝网络和 VPN 接口是三个彼此独立的网络,隧道一建立就成为默认。所以办公室 Wi-Fi 上生效的后缀,并不自动是隧道启用期间生效的后缀。要检查应用真正被选中的那个网络,而不是你上周配置的那个。

设备上的终端 shell 在这里是糟糕的证人,因为它的resolv.conf只反映解析器的一种视角,而不是每个应用的视角。

浏览器地址栏又加了一层:裸词可能被当成搜索词,也可能经由浏览器自己的加密 DNS 策略来解析,所以在 Chrome 里能打开页面,并不能证明系统的名字解析。请用真正调用平台解析器并打印返回值的东西来测。然后在同一个会话、同一个网络上分别跑短名和完整名,记下哪一个得到了应答。

如果你是 VPN 应用的开发者,就在构建器里附上后缀

当应用通过VpnService建立接口时,addSearchDomain才是这件事受支持的输入。它接收corp.example这样的域字符串,而不是另一种传服务器地址的方式。

这次调用把后缀绑定到你正在构建的那个网络上,之后没有全局开关可翻。如果应用拆掉接口、在重连时重新构建,新的构建器必须再次加上后缀,否则替换上来的网络就没有它。

桌面端配置文件导入丢的往往就是这个字段。导出方把域写进自己的模型,Android 前端只映射它认识的选项,最后的接口在别的方面看起来都对。在笔记本上能用、在手机上失效的配置,通常是映射缺口,而不是协议问题。

如果你只是使用 VPN,这件事不该由你来设

客户端侧没有能添加后缀的编辑入口,也没有能伪造它的全局属性。这个值由拥有隧道的一方下发:托管客户端的配置里、它按平台的映射里,或者服务器推送的内容里。说清楚你在哪个平台、哪个名字失败,因为桌面端和移动端的前端恰恰在这个字段上分道扬镳。

再导入一次桌面配置,依然证明不了移动端的映射。

三个条件决定你遇到的是缺陷还是预期内的限制。第一,组织到底把短名当作受支持的名字,还是它从来只在办公室 Wi-Fi 里凑巧能用?第二,失败的查询是不是来自浏览器,而浏览器可以完全绕过系统解析器?第三,短名本来就应该通过隧道访问,还是只该在局域网内可用?如果最后一条答案是仅限局域网,那么加上后缀只会造出一个在办公室外能解析、却路由不到的名字。

后缀已经存在,短名仍然失败时

如果域搜索列表里已经出现corp.example,就别再怪后缀了。先确认解析器对展开后的名字到底有没有应答,因为后缀改变的只是你问的问题。它从不会让服务器对它并不托管的区拥有权威。

然后检查路由。能解析、但隧道不承载的地址会在连接时失败,这和在浏览器里悄悄放弃的解析失败看起来一模一样。

证书值得单独一提。HTTPS 校验用的是你真正输入的主机名,所以能正确展开的短名,在握手时出示的仍然是files。为files.corp.example签发的证书不会对它生效,而这个报错是正确行为,不是最初那个 DNS 问题的症状。

接下来该做什么

动手之前先确认拆分:完整名能解析、短名不能,同一个应用、同一个会话。然后找到被选中的网络,把它的域搜索列表和解析器列表并排读一遍。两者中哪个是空的,就说明该谁动手——你有应用就由你改,没有就找隧道运营方。

最后,在需要可移植性的地方,书签和客户端配置里尽量用完整的服务主机名。它能跨过网络切换,不依赖移动端可能没实现的映射,也和证书签发时用的名字一致。

相关文章