编码代理与终端 · 收录于 2026-08-31 · 适用 1 工具 ✓ 实测验证

WSL 里报 Temporary failure in name resolution / 连不上网,VPN 一连上 WSL 就断网

已验证 2026-08-31WSL 报 name resolution 失败/VPN 一连就断网——systemd 发行版给 stub 换可达上游(DNS=223.5.5.5 119.29.29.29)并重启 systemd-resolved。

快速修复

# 立即恢复(systemd 发行版,Ubuntu 22.04+):给 stub 换可达上游并生效
sudo sed -i 's/^#*DNS=.*/DNS=223.5.5.5 119.29.29.29/' /etc/systemd/resolved.conf
sudo systemctl restart systemd-resolved
getent hosts github.com   # 返回 IP = 修好了

# 非 systemd 发行版:直接写 resolv.conf(重启后可能被覆盖,见「一步步来」治本)
sudo sh -c 'echo "nameserver 223.5.5.5" > /etc/resolv.conf'

你会遇到什么

WSL 里 curl / git clone / apt update 报 Temporary failure in name resolution(或 无法解析主机名),但 Windows 侧上网正常;典型场景:VPN 一连上,WSL 就断网;或每次重启 WSL 后 /etc/resolv.conf 被 Windows 重写成失效地址。

诊断口诀:先分清是「解析不了名字」还是「路由不通」——ping 8.8.8.8 通但 ping github.com 报解析失败 = DNS 问题,本文管的就是这个。

本文路径:快速修复(30 秒一段命令)→ 一步步排查(可跳读)→ 原理与变体(症状/原因/证据)。赶时间直接跳到「快速修复」。

为什么会这样

先说结论:这不是 WSL 坏了,而是「DNS 上游不可达」。整条解析链路只会断在三个点:resolv.conf 被覆盖、stub 上游不可达、NAT 通道被 VPN 破坏。下面拆开讲,方便你对号入座。

链路:DNS 是 Windows 侧「抄」给 WSL 的。

WSL2 网络是一张 NAT 虚拟交换机,WSL 没有自己的物理网卡,DNS 只能依赖 Windows 侧下发。generateResolvConf=true 时,每次启动 WSL 都会重写 /etc/resolv.conf。

systemd 发行版(Ubuntu 22.04+)的 /etc/resolv.conf 实际指向 stub 127.0.0.53——stub 自己不解析,只把查询转发给上游。上游来自 Windows 侧 DNS,用 resolvectl status 能直接看到。

VPN 的坑:上游只在隧道内可达。

VPN 一连上,Windows 就把 VPN 的 DNS 抄给 WSL。这个 DNS 服务器只在隧道内可达,stub 在隧道外转发必然失败——于是报 Temporary failure in name resolution。

三个断点,对应三类修法:

  1. resolv.conf 被覆盖/写错 → 固定它:generateResolvConf=false + 手动 nameserver;
  2. stub 上游不可达(典型:VPN DNS 在隧道内)→ 换上游:/etc/systemd/resolved.conf 的 DNS= 或 resolvectl;
  3. NAT 转发本身被 VPN 破坏 → 绕开 NAT 的 DNS 通道:.wslconfig 开 dnsTunneling=true(DNS 查询走 Windows 侧处理)或 networkingMode=mirrored(WSL 与 Windows 共享网络栈)。

注意:generateResolvConf=false 只阻止「被覆盖」,不保证「上游可达」——它只治断点 1,治不了断点 2 和 3。

本机实测(2026-08-31):resolv.conf = stub(127.0.0.53)、上游 = 223.5.5.5/119.29.29.29(来自 resolved.conf 配置)、getent hosts github.com 正常。

把 resolv.conf 指向不可达地址(203.0.113.1)后,getaddrinfo 报 [Errno -3] Temporary failure in name resolution;恢复后解析正常——「nameserver 指向不可达地址 = 这个报错」的链路成立。

确定性推论:先 resolvectl status 看上游。上游不可达 → 换可达 DNS;上游正常还断网 → 是路由/通道问题(用 ping 8.8.8.8 验证),往 dnsTunneling / mirrored 方向查。

一步步来

1. 分清 DNS 还是路由 — 必做(30 秒定位)

ping -c1 223.5.5.5        # 通 = 路由没问题;不通 = 网络通道问题(VPN/虚拟交换机)
getent hosts github.com   # 通 = DNS 没问题;报 Temporary failure = DNS 问题,往下走

2. 看当前解析链路 — 必做(知道断在哪一层)

cat /etc/resolv.conf      # stub=127.0.0.53(systemd)或直接 nameserver(非 systemd)
resolvectl status         # systemd:看 Current DNS Server / DNS Servers(上游从哪来)

上游是 127.0.0.53 且系统解析失败 → 换上游(快速修复段);resolv.conf 直接是失效地址 → 修它。

3. 固定 resolv.conf,防重启被覆盖 — 治本(generateResolvConf 开关)

# /etc/wsl.conf
[network]
generateResolvConf = false

然后 wsl --shutdown 重开。注意:systemd 发行版推荐保留 stub、改 resolved.conf 上游(快速修复段),不要手动写 nameserver 覆盖 stub(会与 systemd-resolved 打架);非 systemd 发行版才手动写 resolv.conf。

4. VPN 场景:换通道 — 按场景(VPN 一连上 WSL 就断)

VPN 的 DNS 只在隧道内 → 换公共 DNS 无效时,改通道:

# %USERPROFILE%\.wslconfig(Windows 侧)
[wsl2]
dnsTunneling=true        # DNS 查询走 Windows 侧(官方推荐 VPN 场景先试这个)
# networkingMode=mirrored  # 更彻底:WSL 与 Windows 共享网络栈(二选一)

wsl --shutdown 后重开。官方 troubleshooting 还给了手动兜底:记下 VPN 的 DNS 服务器,写进 resolv.conf。

5. 其它断点 — 排查(少见但真实)

IPv6 被禁用(注册表 DisabledComponents)→ WSL 网络可能异常;.wslconfig 配置语法错误 → wsl --shutdown 后整段不生效,先 wsl --version 确认版本支持(dnsTunneling 需 WSL 2.2+)。

怎么确认修好了

getent hosts github.com && curl -I --max-time 8 https://github.com | head -1
# getent 返回 IP、curl 返回 HTTP/2 200 = 全链路通
wsl --shutdown && wsl -d Ubuntu   # 重启后仍通 = 治本成功(防覆盖配置生效)

其它环境的表现

环境说明
Ubuntu 22.04+(systemd)走 stub,改 resolved.conf 上游;不要手动覆盖 resolv.conf
老发行版(非 systemd)直接写 resolv.conf + generateResolvConf=false
VPN 场景换公共 DNS 无效 → dnsTunneling=true / mirrored(.wslconfig,需 WSL 2.2+)
generateResolvConf=false 已设阻止覆盖,但上游不可达照样断——查 resolvectl status

症状

$ curl -I https://github.com
curl: (6) Could not resolve host: github.com
$ apt update
Temporary failure resolving 'archive.ubuntu.com'
$ getent hosts github.com
(无输出,exit=2)

特征:Windows 侧上网正常;ping 8.8.8.8 通但域名全解析失败;VPN 一连上就断;重启 WSL 后复发(被覆盖)。

原因

WSL2 NAT 模式下 DNS 由 Windows 侧下发:generateResolvConf=true 每次启动重写 /etc/resolv.conf;systemd 发行版走 stub(127.0.0.53)再转发上游;VPN 的 DNS 在隧道内不可达 → 转发失败 → Temporary failure in name resolution。三个断点:resolv.conf 被写错/覆盖、stub 上游不可达、NAT 通道被 VPN 破坏。

解法

  1. 定位:ping 223.5.5.5(路由)vs getent hosts github.com(DNS);2. systemd 发行版:/etc/systemd/resolved.conf 设 DNS=223.5.5.5 119.29.29.29 + systemctl restart systemd-resolved;3. 防覆盖:/etc/wsl.conf generateResolvConf=false;4. VPN 场景:.wslconfig dnsTunneling=true 或 networkingMode=mirrored;5. 验证:getent hosts github.com + curl -I,重启 WSL 后仍通。
验证证据
  • 本机实测(2026-08-31,定制预构建版 WSL,DNS 机制与 WSL 版本无关):实测复现日志(2026-08-31)
  • 基线:resolv.conf=stub(127.0.0.53)、resolved.conf 上游=223.5.5.5/119.29.29.29、getent hosts github.com → 20.205.243.166;
  • 复现:resolv.conf 指向不可达地址(203.0.113.1)→ getaddrinfo 报 [Errno -3] Temporary failure in name resolution、getent exit=2;UDP 探测 127.0.0.53 正常应答 / 203.0.113.1 超时;
  • 恢复:还原 resolv.conf 后解析恢复正常(trap 兜底 + 显式恢复,无残留);
  • 治本配置与本文推荐一致:wsl.conf generateResolvConf=false + resolved.conf 公共上游。
  • 未实测(如实标注):VPN 场景(本机无 VPN)、dnsTunneling/mirrored 切换(会动网络栈)。

相关 canonical

按「前置 → 同根 / 同域 / 相关」读:

  • 只有个别网站打不开(其他网站正常)——分层定位(相邻:单域名失败,同一套分层法)
  • 相关(报错相近,根因不同):
  • 本页是「WSL 网络/DNS」canonical;相邻 WSL 问题:wsl-register-failed(启动就失败)、wsl-no-space-left(启动后写不进盘)、wsl-pipe-encoding(PowerShell 调 wsl 乱码)。

适用工具 (1)

本问题方案已挂到下列工具的方案页——从工具页也能回到这里,双向可达。

wsl · 外部工具

来源与证据

收录 验证 ✓ 实测验证适用 1 工具
方案含本地实测或来源可复核的解法;未实测项已在文中如实标注。

素材来源:https://learn.microsoft.com/windows/wsl/troubleshooting

这条方案对你有用吗?

反馈由维护 Agent 汇总,用于重测排期与方案改进;匿名,不收集任何个人信息。

← 编码代理与终端 问题域 | 问题货架 | 遇到其它问题?去 问题空间 提交求助卡