有一种 VPS 故障很烦:服务器看起来没断网,ping 1.1.1.1 能通,SSH 也能连,但 apt update、curl https://example.com、应用请求第三方 API 全部报错。
报错通常长这样:
Temporary failure in name resolution
Could not resolve host
Name or service not known
这时候别急着重启整台机器。很多时候不是 VPS 网络断了,而是 DNS 解析挂了。
简单说,IP 能通但域名不通,就是“路还在,电话簿坏了”。这篇按排查顺序讲:怎么确认是不是 DNS,怎么查 systemd-resolved,/etc/resolv.conf 为什么会坏,127.0.0.53 是什么,临时怎么恢复,最后怎么避免下次又被覆盖。
第一步不要猜,直接做对比测试。
先 ping 一个 IP:
ping -c 3 1.1.1.1
再 ping 一个域名:
ping -c 3 example.com
如果 IP 能通,域名不通,大概率就是 DNS 解析问题。
再用 curl 对比:
curl -I https://1.1.1.1
curl -I https://example.com
https://1.1.1.1 可能会因为证书域名不匹配报 TLS 错,但只要能连接到对方,说明网络层大致没断。真正要看的,是域名解析有没有失败。
安装了 dig 的话更直观:
dig example.com
如果系统默认 DNS 查不出来,再指定公共 DNS:
dig @1.1.1.1 example.com
dig @8.8.8.8 example.com
如果 dig @1.1.1.1 example.com 能查到,而 dig example.com 查不到,说明公网 DNS 服务没问题,问题在你这台 VPS 的本机解析配置。
Ubuntu 20.04/22.04/24.04 这类系统上,常见组件是 systemd-resolved。先看状态:
resolvectl status
重点看几块:
- Global 有没有 DNS Servers
- 当前网卡有没有 DNS Servers
- DNSSEC 是 yes、no 还是 allow-downgrade
- DNSOverTLS 是否开启
- 当前 DefaultRoute 接口是谁
也可以直接查一个域名:
resolvectl query example.com
如果这里失败,但 dig @1.1.1.1 example.com 成功,问题就集中在本机 resolver 或接口 DNS 配置上。
再看服务状态:
systemctl status systemd-resolved --no-pager
看最近日志:
journalctl -u systemd-resolved --since "30 minutes ago" --no-pager
如果正在排查线上故障,可以实时看:
journalctl -u systemd-resolved -f
Ubuntu 的 DNSSEC 排查文档也会用 resolvectl、dig 和 journalctl 组合定位解析问题,这套命令比“重启试试”靠谱得多。
很多人第一次看到 /etc/resolv.conf 里只有这一行,会以为 DNS 被改坏了:
nameserver 127.0.0.53
其实这通常是 systemd-resolved 的本地 stub resolver。应用把 DNS 请求发到 127.0.0.53,再由 systemd-resolved 转发到真正的上游 DNS。
先看 /etc/resolv.conf 到底是什么:
ls -l /etc/resolv.conf
readlink -f /etc/resolv.conf
cat /etc/resolv.conf
常见正常情况之一是它指向:
/run/systemd/resolve/stub-resolv.conf
里面有:
nameserver 127.0.0.53
也有些系统会直接指向:
/run/systemd/resolve/resolv.conf
里面会写真实上游 DNS。两种模式都可能正常,关键是要和你的系统网络管理方式一致。
真正危险的是:
/etc/resolv.conf被手工写死,重启后又被覆盖- 文件指向不存在的路径
- nameserver 写成内网不可达地址
- 只有 IPv6 DNS,但 VPS IPv6 路由不通
- 面板、VPN、Docker、cloud-init 抢着改 DNS
DNS 故障不要只跑一条命令。可以按这组顺序来:
dig example.com
dig @127.0.0.53 example.com
dig @1.1.1.1 example.com
dig @8.8.8.8 example.com
几种结果很好判断:
| 结果 | 说明 |
|---|---|
@1.1.1.1 成功,默认失败 | 本机 resolver / resolv.conf 问题 |
@127.0.0.53 失败,@1.1.1.1 成功 | systemd-resolved 或它的上游配置有问题 |
| 所有公共 DNS 都失败 | 可能是域名本身、VPS 出站 UDP/TCP 53、网络策略问题 |
| 只有某个域名失败 | 可能是 DNSSEC、权威 DNS、域名配置或缓存问题 |
| A 记录成功,AAAA 卡住 | IPv6 DNS/网络配置可能有坑 |
有些 VPS 商或公司网络会拦截 UDP 53,也可以试试 TCP:
dig +tcp @1.1.1.1 example.com
如果 UDP 失败、TCP 成功,就要怀疑防火墙、运营商策略或本机规则。
线上服务正在报错时,目标是先恢复解析,再慢慢找根因。
如果你知道网卡名,比如 eth0,可以临时设置:
sudo resolvectl dns eth0 1.1.1.1 8.8.8.8
sudo resolvectl domain eth0 '~.'
然后测试:
resolvectl query example.com
dig example.com
curl -I https://example.com
如果网卡不叫 eth0,先看:
ip link
resolvectl status
这类 resolvectl dns 设置偏运行时,适合救急。要永久生效,还要回到 netplan、NetworkManager、cloud-init 或系统网络配置里处理。
如果想撤销接口上的临时设置:
sudo resolvectl revert eth0
有时候不是 DNS 配置完全错,而是缓存或 server feature 探测状态异常。
可以清 DNS 缓存:
sudo resolvectl flush-caches
再重置 DNS 服务器特性探测:
sudo resolvectl reset-server-features
然后再查:
resolvectl query example.com
resolvectl 官方手册里就有 flush caches、reset server features、按接口设置 DNS、revert 接口配置这些操作。排查时先用这些有边界的命令,不要一上来就乱删配置文件。
如果 systemd-resolved 状态异常,可以重启它:
sudo systemctl restart systemd-resolved
然后马上看:
systemctl status systemd-resolved --no-pager
resolvectl status
resolvectl query example.com
不建议第一反应就 reboot。重启整台 VPS 会中断业务,而且如果 /etc/resolv.conf 或 netplan 配置本来就是错的,重启后问题还在。
如果你重启服务后好了,也要继续问一句:为什么它会坏?是缓存、上游 DNS、DHCP 下发、DNSSEC,还是某个工具改了配置?
很多教程会教你这样:
sudo nano /etc/resolv.conf
然后写:
nameserver 8.8.8.8
nameserver 1.1.1.1
短时间可能有效,但经常会被 NetworkManager、netplan、systemd-resolved、cloud-init 或 DHCP 客户端覆盖。
如果只是救急,可以临时写,但要知道它可能不持久。更稳的做法是找出谁在管理网络。
Ubuntu 常见是 netplan:
ls /etc/netplan/
看配置:
sudo cat /etc/netplan/*.yaml
如果是 netplan,可以在对应网卡下配置 nameservers,例如:
network:
version: 2
ethernets:
eth0:
dhcp4: true
nameservers:
addresses:
- 1.1.1.1
- 8.8.8.8
改完先检查再应用:
sudo netplan try
sudo netplan apply
远程 VPS 上改 netplan 要非常小心。netplan try 会给你回滚机会,别直接把自己踢下线。
很多 VPS 第一次开机由 cloud-init 写网络配置。你手工改了 netplan,过段时间重启或重建后又被覆盖,就要看看 cloud-init。
常见文件:
ls /etc/cloud/cloud.cfg.d/
如果你明确不想让 cloud-init 管网络,有些系统会用类似配置:
network: {config: disabled}
但不要随便照抄。云厂商模板不一样,禁用 cloud-init 网络管理可能影响后续改 IP、换网卡、重建实例。生产机器上动这个之前,先确认云厂商文档和当前网络配置。
对普通用户来说,更安全的做法是:先找出 DNS 是从 DHCP、netplan、NetworkManager 还是 cloud-init 来的,再决定在哪里改。
如果只是个别域名解析失败,而公共 DNS 结果不一致,可以怀疑 DNSSEC、权威 DNS 或缓存问题。
看 resolved 状态:
resolvectl status
看 DNSSEC 相关日志:
journalctl -u systemd-resolved --since "30 minutes ago" --no-pager
用 dig 看 DNSSEC 信息:
dig example.com +dnssec
再指定不同上游:
dig @1.1.1.1 example.com +dnssec
dig @8.8.8.8 example.com +dnssec
如果只在开启 DNSSEC 验证时失败,可能是域名 DNSSEC 配置坏了,也可能是中间网络或上游 DNS 支持不完整。
不建议为了一个域名长期关闭所有 DNSSEC。更好的做法是先确认是不是域名权威 DNS 的问题,再决定是否临时降级。
宿主机能解析,不代表容器里一定能解析。
进容器测试:
docker exec -it 容器名 sh
nslookup example.com
cat /etc/resolv.conf
Docker 默认会给容器生成自己的 /etc/resolv.conf。如果宿主机 DNS 变化后容器没跟上,或者 Docker daemon 配了错误 DNS,容器内应用就会报 Could not resolve host。
可以看 Docker daemon 配置:
sudo cat /etc/docker/daemon.json
如果要给 Docker 固定 DNS,常见写法是:
{
"dns": ["1.1.1.1", "8.8.8.8"]
}
改完需要重启 Docker:
sudo systemctl restart docker
注意:重启 Docker 会影响容器,生产环境要安排窗口。
宝塔、1Panel、VPN 客户端、代理工具、内网穿透工具,都可能改 DNS 或路由。
排查时看最近改动:
stat /etc/resolv.conf
ls -lt /etc/netplan/
journalctl --since "2 hours ago" --no-pager | grep -i dns
如果故障发生在你安装 VPN、改安全组、装面板、调整 Docker 网络之后,优先回看那次改动。DNS 问题经常不是“突然坏了”,而是某个工具替你改了网络配置。
线上正在挂,按这个顺序走:
ping -c 3 1.1.1.1看 IP 通不通ping -c 3 example.com看域名解析是否失败dig @1.1.1.1 example.com验证公共 DNS 是否能查resolvectl status看当前 DNS 和接口readlink -f /etc/resolv.conf看 resolv.conf 指向journalctl -u systemd-resolved --since "30 minutes ago"看日志sudo resolvectl flush-caches清缓存sudo resolvectl reset-server-features重置探测状态sudo resolvectl dns eth0 1.1.1.1 8.8.8.8临时指定 DNSresolvectl query example.com验证恢复- 再回头修 netplan / NetworkManager / cloud-init 的持久配置
这套流程的重点是先分层:网络通不通、本机 resolver 好不好、上游 DNS 能不能查、配置会不会被覆盖。
- IP 能通,域名不通,确认是 DNS 方向
-
dig @1.1.1.1 example.com能验证公网 DNS -
resolvectl status看到了当前接口 DNS -
systemd-resolved服务状态正常 -
/etc/resolv.conf指向合理,没有坏链接 -
127.0.0.53是 stub resolver,不是天然错误 - 已清缓存和 reset server features
- 临时 DNS 设置后解析恢复
- 持久配置回到 netplan / NetworkManager / cloud-init
- Docker 容器内 DNS 也单独测试过
- 没有用
reboot掩盖根因
DNS 故障看起来很玄,其实拆开就几层:应用问谁、systemd-resolved 转给谁、上游 DNS 回不回、配置会不会被其他工具覆盖。只要 IP 能通,就别急着怀疑整个 VPS 坏了,先把解析链路一层层查清楚。
