OpenConnect 无法解析域名?从 DNS 到路由的一站式排查与修复指南

遇到域名无法解析时先别慌——从现象到根因的一条路

当使用 OpenConnect 连接企业或个人的 VPN 时,最常见的抱怨之一是“能连上,但无法解析远程域名”。这类问题看起来像 DNS 问题,但背后经常牵扯到路由、系统解析器与 VPN 推送策略之间的互动。本文以实际故障排查为主线,带你从 DNS 层面逐步延伸到路由与系统服务,帮你快速定位并修复问题。

先搞清楚发生了什么(场景还原)

常见症状包括:

  • VPN 已建立,能通过 IP 访问远程资源,但无法通过域名访问。
  • 本地浏览器能解析公网域名,但企业内部域名无法解析。
  • 断开 VPN 后,域名解析恢复正常或变成本地 DNS 解析。

这些现象提示主要问题集中在“DNS 请求没有走到预期的 DNS 服务器”或“路由策略把 DNS 流量送错了地方”。

背后的原理梳理(关键链路)

把整个过程抽象为三段链路:

  1. 应用/系统发起 DNS 查询 → 本地解析器(如 systemd-resolved、dnsmasq、NetworkManager)
  2. 解析器根据配置决定将请求转发到哪个上游 DNS(本地 ISP、企业 DNS、DoH/DoT 等)
  3. 网络层的路由/防火墙决定 DNS 包是否走到上游 DNS(通过 IP 路由、策略路由或防火墙拦截)

OpenConnect 在连接建立时通常会“推送”若干信息给客户端,包括路由表、DNS 服务器和域名匹配规则(split DNS)。客户端解析器需要正确接收并应用这些配置才能让内部域名正常解析。

典型原因与细化分析

1. 客户端解析器没有正确应用 VPN 推送的 DNS

很多 Linux 发行版使用 systemd-resolved 或 NetworkManager。OpenConnect 建立后,如果客户端没有把推送的 DNS 写入到 systemd 的接口域名配置,解析器仍然使用原来的上游,导致内部域名无法解析。

2. /etc/resolv.conf 被覆盖或指向本地 stub(127.0.0.53)

当 /etc/resolv.conf 指向系统 stub resolver 时,真正的上游由 systemd-resolved 管理。如果 NetworkManager 未通知 systemd-resolved 使用 VPN 的 DNS,上游就不会变化。

3. Split DNS 策略未生效

企业常只希望内部域名走企业 DNS(而把其他流量走公网)。如果客户端没有安装相应的域名匹配规则(比如对特定域名走企业 DNS),内部域名解析会落空。

4. 路由或防火墙阻止 DNS 请求

即便 DNS 配置正确,路由表或 iptables/nftables 规则也可能把 UDP/TCP 53 的流量重定向或丢弃,或者策略路由让 DNS 包走了错误的接口(本地网关而非 tun/ppp 接口)。

5. DNS over TLS/HTTPS 与传统 DNS 的冲突

如果客户端启用了 DoH/DoT(浏览器内或系统级),这些隧道可能绕过本地解析器的配置,导致查询不经过 VPN 指定的 DNS。

一套可复用的排查步骤(从易到难)

以下步骤面向有 Linux 使用经验的技术爱好者,按顺序进行可以快速缩小问题范围。

  1. 确认连接状态:确认 OpenConnect 显示连接成功,且相关虚拟接口(例如 tun0/ppp0)存在。
  2. 查看当前 DNS 配置:检查 /etc/resolv.conf 的内容以及 systemd-resolved 的接口配置,判断 DNS 是否被 VPN 推送覆盖。
  3. 验证解析器行为:对内部域名和外部域名分别发起查询(使用能够选择上游的工具或观察解析器日志),看请求是否到达预期 DNS。
  4. 检查路由与策略路由:查看主路由表及策略路由(ip route, ip rule),确认到 DNS 服务器的下一跳指向 VPN 接口。
  5. 排查防火墙:检查本机及中间网关是否有针对 53 端口的拦截或重写规则。
  6. 观察 systemd-resolved / NetworkManager 日志:这些日志会提示 DNS 服务器是如何被添加或拒绝的。
  7. 临时验证法:在客户端上指定远程 DNS(如果可能)并强制走 VPN 接口,观察是否解决问题,从而判断问题在 DNS 还是路由层。

修复策略(按症状对应解决)

DNS 未被正确写入 systemd-resolved / resolv.conf

确保 NetworkManager 的 dns 配置允许使用 systemd-resolved,并查看 OpenConnect 客户端或脚本是否触发了 NM dispatcher。必要时在连接后手动把 VPN 提供的 DNS 加到 systemd 的接口配置。

split DNS 没生效

如果需要按域名走企业 DNS,要确认 OpenConnect 推送了域名规则并且客户端解析器支持该规则(systemd-resolved 支持 per-link domains)。在不支持时可以借助 NetworkManager 的 dispatcher 脚本或第三方工具实现域名到指定上游的转发。

路由导致 DNS 流量走错接口

调整策略路由,使到 DNS 服务器的流量走 VPN 接口;或在防火墙上做 DNAT,把目的为外部 DNS 的包重定向到 VPN 提供的 DNS(谨慎使用,确认不会影响其它功能)。

DoH/DoT 干扰

如浏览器或系统启用了 DoH/DoT,临时禁用以排查。若确认为此类服务导致解析绕行,需要在客户端策略层面禁用或将其配置为通过 VPN 隧道。

一个简短的示例输出(帮助你对照现状)

/etc/resolv.conf 内容示例(用于肉眼比对)

nameserver 127.0.0.53 <-- 指向 systemd stub 或者直接是 VPN DNS IP search corp.example.com <-- VPN 推送的域搜索

工具与日志:哪里能看到有用线索

关注以下信息来源能最快找到问题点:

  • OpenConnect 控制台输出与日志:查看有没有 DNS 推送或脚本错误。
  • systemd-resolved 日志与状态(如链接的 DNS 列表、Per-link domains)。
  • NetworkManager 日志:看是否在连接时覆盖了 DNS。
  • 路由与策略(ip route, ip rule)的当前表。
  • 防火墙(iptables/nftables)规则和 nat 表。

常见误区与注意点

  • 不要只看 /etc/resolv.conf,一些系统使用 stub resolver,实际上游被 systemd 管理。
  • 不要假设“能 ping 域名的 IP”就说明 DNS 完全正常:有时是缓存或本地 hosts 的结果。
  • 对企业环境,确认是否存在 DNS 策略(如仅允许企业网段访问内网 DNS)。

最后一点思路:把复杂问题分解成“谁负责”和“包走哪儿”两步

遇到解析失败,先问两个问题:1) 谁被配置为负责解析(哪个解析器/上游)?2) DNS 包物理/逻辑上走到哪里(哪个接口/网关/被拦截)?把问题拆成这两部分,通常能快速定位到底是配置应用问题还是路由/防火墙问题。

通过上述方法,你可以系统排查 OpenConnect 下的域名解析问题,从 DNS 设置、解析器行为到路由与防火墙三层定位与修复。掌握这些思路后,面对各类变体(不同发行版、不同 NetworkManager 配置或企业策略)也能快速适配。

© 版权声明
THE END
喜欢就支持一下吧
分享
评论 抢沙发

请登录后发表评论

    暂无评论内容