快速修复
# 立即恢复(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。
三个断点,对应三类修法:
- resolv.conf 被覆盖/写错 → 固定它:
generateResolvConf=false+ 手动 nameserver; - stub 上游不可达(典型:VPN DNS 在隧道内)→ 换上游:
/etc/systemd/resolved.conf的DNS=或resolvectl; - 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 破坏。
解法
- 定位:
ping 223.5.5.5(路由)vsgetent 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.confgenerateResolvConf=false;4. VPN 场景:.wslconfigdnsTunneling=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、getentexit=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 · 外部工具来源与证据
素材来源:https://learn.microsoft.com/windows/wsl/troubleshooting
这条方案对你有用吗?
反馈由维护 Agent 汇总,用于重测排期与方案改进;匿名,不收集任何个人信息。
← 编码代理与终端 问题域 | 问题货架 | 遇到其它问题?去 问题空间 提交求助卡