VPS能访问IP却解析不了域名?从resolv.conf到出站53端口逐层排查

先判断是全机DNS故障、单个应用问题,还是错误修改被系统自动覆盖
发布于
10

VPS能访问公网IP却解析不了域名,说明问题很可能位于名称解析链,但这还不能直接证明“DNS服务器坏了”。应用可能绕过系统解析器,/etc/resolv.conf可能指向本地存根,出站UDP或TCP 53端口也可能被防火墙、安全组或上游网络拦截。正确做法是从现象开始,逐层确认请求在哪一段消失。

先确认故障边界:一个程序,还是整台VPS

不要一上来就改DNS地址。先在同一时间窗口执行:

ip route
getent ahosts example.com
resolvectl query example.com
dig example.com A +time=2 +tries=1

getent走系统名称服务配置,更接近多数应用实际调用;resolvectl适用于使用systemd-resolved的系统;dig用于直接观察DNS响应。某条命令不存在不代表DNS故障,只说明对应工具未安装或该发行版没有启用相应组件。

现象 优先检查
所有命令都失败 系统DNS配置、上游可达性、53端口
dig成功,getent失败 nsswitch.conf、本地解析服务、缓存
宿主机成功,容器失败 容器resolv.conf、Docker DNS、容器网络
只有某个应用失败 应用自带DNS、代理变量、沙箱或缓存
A记录正常,连接仍失败 AAAA优先、路由、TLS或应用端口,不一定是DNS

确认resolv.conf到底由谁管理

ls -l /etc/resolv.conf
readlink -f /etc/resolv.conf
cat /etc/resolv.conf
grep '^hosts:' /etc/nsswitch.conf

/etc/resolv.conf可能是普通文件,也可能链接到systemd-resolved生成的存根文件;在其他系统中,还可能由NetworkManager、DHCP客户端或cloud-init维护。看到127.0.0.53不等于配置错误,它通常表示请求先交给本机的systemd-resolved。

直接覆盖文件、加不可变属性,常会造成“暂时好了,重启又坏”或内网服务域名失效。先识别管理者,再修改相应的网络连接、resolved配置或云平台网络设置。

如果使用systemd-resolved,检查服务与上游

systemctl status systemd-resolved --no-pager
resolvectl status
journalctl -u systemd-resolved --since "-15 min" --no-pager

重点看当前网卡是否拿到DNS服务器、默认路由域是否合理、服务是否反复重启,以及日志里是否持续出现超时。若服务未启用,不要为了照抄教程强行切换解析架构;先确认发行版原本使用什么组件。

修改配置前保留当前输出。完成调整后优先使用systemctl reload-or-restart systemd-resolved或发行版推荐方式,并再次执行resolvectl status。生产机上不要在没有控制台或第二条管理通道时连续重启网络服务。

绕过本机配置,直接测试指定DNS

dig @1.1.1.1 example.com A +time=2 +tries=1
dig @1.1.1.1 example.com A +tcp +time=2 +tries=1

这里的公共地址仅用于一个受控诊断样本,能否使用取决于服务器所在网络和组织策略。第一条通常使用UDP,第二条强制TCP。两者都失败,而其他公网连接正常时,应继续查主机防火墙、云安全组、网络ACL或服务商对出站53端口的限制。UDP成功、TCP失败,则可能在响应截断或需要TCP回退时出现间歇性故障。

如果云平台提供内网DNS,优先核对平台文档与控制台下发值。擅自换成公共DNS可能导致私有域名、服务发现或合规策略失效。

主机防火墙与出站规则要查两个方向

DNS查询通常使用UDP 53,也会使用TCP 53。主机上可根据实际防火墙选择查看命令:

nft list ruleset
iptables -S
ufw status verbose

这些命令用于读取现状,不要在不清楚规则来源时直接清空防火墙。还应检查云控制台的安全组、网络ACL和企业出口策略;主机允许并不代表上游允许。若使用DNS over HTTPS或DNS over TLS,则排查端口和证书链也会不同,不能拿传统53端口测试代替。

容器、代理与应用自带DNS是三条分支

Docker容器

Docker容器常看到127.0.0.11,这是Docker内置解析器,不是宿主机的127.0.0.1。在问题容器中检查:

cat /etc/resolv.conf
getent ahosts example.com

同时核对容器网络、Docker守护进程的DNS设置和转发规则。宿主机正常、容器失败时,不要反复修改宿主机的resolv.conf。

HTTP或SOCKS代理

有的客户端在本地解析域名后把IP交给代理,有的会把域名交给代理端解析。检查应用的代理模式与HTTP_PROXYHTTPS_PROXYNO_PROXY等环境变量,确认故障发生在VPS本地还是远端代理解析。

应用缓存

Java、浏览器、数据库连接池和常驻进程可能缓存解析结果。系统查询已经恢复而应用仍报错时,先查应用日志与缓存周期,再按维护流程重载应用,不要把重启整台VPS当作第一选择。

修复后要验证的不只是dig

  1. getent ahosts能够通过系统解析器返回预期记录;
  2. 默认查询和TCP查询在需要时都能完成;
  3. 目标应用能够建立真实连接,而不只是得到IP;
  4. 容器、定时任务和系统服务使用的运行环境也通过;
  5. 重启网络服务或在维护窗口重启后,配置没有被重新覆盖;
  6. 私有域名、搜索域和IPv6解析没有因临时修复受损。

需要比较dignslookup与系统查询工具的区别,可阅读极跃圈的DNS排查命令选择说明。如果问题只在VPS重启后出现,还应结合VPS重启后服务恢复顺序检查网络在线依赖和服务启动时机。

结论

VPS DNS解析失败的排查顺序应是:先划定应用或全机故障,再确认系统解析器和resolv.conf的管理者,然后分别测试上游DNS、UDP与TCP 53端口,最后进入容器、代理和应用缓存分支。每次只改变一层并保留前后结果,才能避免“改了很多配置但不知道哪一步生效”。

常见问题(FAQ)

VPS能ping通IP就能证明网络正常吗?
不能完全证明。它只能说明对应IP的ICMP路径可能可用,不能证明TCP、UDP、路由、代理或DNS端口都正常。还需要分别测试系统解析、指定DNS查询和实际业务连接。
可以直接把resolv.conf改成公共DNS吗?
不建议先改。该文件可能由systemd-resolved、NetworkManager、DHCP或cloud-init生成,手工内容会被覆盖,也可能破坏内网域名解析。应先确认文件来源和云平台要求,再修改对应管理层。
UDP 53可用,为什么DNS仍然偶发失败?
较大响应、截断或部分网络场景可能回退到TCP 53。如果TCP 53被拦截,就会出现小查询正常、大查询失败的现象。可分别用dig默认查询和dig加tcp参数验证。
宿主机能解析,Docker容器不能解析怎么办?
先在容器内查看resolv.conf,并确认Docker内置解析器、上游DNS、网络模式和防火墙。不要因为宿主机正常就跳过容器自己的解析链。

本文由作者原创/授权发布于极跃圈(jiyueip.com)未经许可,禁止转载。题图来自Unsplash,基于CC0协议。

声明:极跃圈(JIYUEIP.com)内网友所发表的所有内容及言论仅代表其本人,并不反映任何极跃圈(JIYUEIP.com)之意见及观点。

0 讨论
热门最新
总结
暂无总结
0 / 600