排查适用于 Linux 的 Windows 子系统问题

下面介绍了一些与 WSL 关联的常见故障排除方案,但请考虑在 GitHub 上的 WSL 产品存储库 中搜索问题。

提交问题、bug 报告、功能请求

WSL 产品仓库问题可以让你:

  • 搜索现有问题 ,查看是否存在与你存在的问题相关的问题。 请注意,在搜索栏中,可以删除“is:open”以包括已在搜索中解决的问题。 请考虑对任何未解决的问题进行评论或点赞,表达你希望将其作为优先事项推动的兴趣。
  • 提交新问题。 如果发现 WSL 存在问题且不存在现有问题,则可以选择绿色 的“新建问题 ”按钮,然后选择 “WSL - Bug 报告”。 你将需要包含问题的标题、Windows 内部版本号(运行 cmd.exe /c ver 以查看当前内部版本号)、你是运行 WSL 1 还是 2、当前 Linux 内核版本号(运行 wsl.exe --statuscat /proc/version)、你使用的发行版版本号(运行 lsb_release -r)、涉及的任何其他软件版本、复现步骤、预期行为、实际行为,以及诊断日志(如果可用且适用)。 有关详细信息,请参阅 参与 WSL
  • 选择绿色的“新建问题”按钮,然后选择“功能请求来提交功能请求。 你需要回答几个描述您请求的问题。

您还可以:

安装问题

  • 安装失败,出现错误0x80070003

    • 适用于 Linux 的 Windows 子系统仅在系统驱动器上运行(通常是你的 C: 驱动器)。 确保分发存储在系统驱动器上:
    • 在 Windows 10 上打开设置 -> -存储 ->
    • 在 Windows 11 上打开“设置-> ->存储 ->高级存储设置 ”->其中保存新内容的系统设置图片,用于在 C: 驱动器上安装应用(Windows 11)
  • WslRegisterDistribution 失败,出现错误0x8007019e

    • 未启用适用于 Linux 的 Windows 子系统可选组件:
    • 打开控制面板 ->程序和功能 ->打开或关闭 Windows 功能 -> 检查适用于 Linux 的 Windows 子系统,或使用本文开头提到的 PowerShell cmdlet。
  • 安装失败,出现错误0x80070003或错误0x80370102

    • 请确保在计算机的 BIOS 中启用虚拟化。 如何执行这一过程的说明因计算机的不同而有所不同,很可能在 CPU 相关选项下找到。
    • WSL2 要求 CPU 支持第二级地址转换(SLAT)功能,该功能是在 Intel Nehalem 处理器(Intel Core 1st Generation)和 AMD Opteron 中引入的。 旧的 CPU(如 Intel Core 2 Duo)将无法运行 WSL2,即使虚拟机平台已成功安装。
  • 尝试升级时出错: Invalid command line option: wsl --set-version Ubuntu 2

    • 确保已启用适用于 Linux 的 Windows 子系统,并且使用的是 Windows 内部版本 18362 或更高版本。 若要启用 WSL,请在具有管理员权限的 PowerShell 提示符下运行以下命令: Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
  • 由于虚拟磁盘系统限制,无法完成请求的作。 虚拟硬盘文件必须未压缩且未加密,并且不得稀疏。

    • 通过打开 Linux 发行版的配置文件夹,取消选择“压缩内容”(如果勾选了“加密内容”,也取消选择)。 它应位于 Windows 文件系统上的文件夹中,如下所示: %USERPROFILE%\AppData\Local\Packages\CanonicalGroupLimited...
    • 在此 Linux 发行版配置文件中,应有 LocalState 文件夹。 右键单击此文件夹以显示选项菜单。 选择“属性 > 高级”,并确保“压缩内容以节省磁盘空间”和“加密内容以保护数据”复选框未选中(未选中)。 如果系统询问是将此应用于当前文件夹还是应用于所有子文件夹和文件,请选择“仅此文件夹”,因为你只是清除压缩标志。 之后,该 wsl --set-version 命令应正常工作。

WSL 发行版属性设置的屏幕截图

注释

在本例中,我的 Ubuntu 18.04 分发版的 LocalState 文件夹位于 C:\Users<my-user-name>\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc

检查 WSL Docs GitHub 线程 #4103 ,其中正在跟踪此问题以获取最新信息。

  • 术语“wsl”无法识别为 cmdlet、函数、脚本文件或可执行程序的名称。

  • 错误:适用于 Linux 的 Windows 子系统未安装分发版。

    • 如果已安装 WSL 分发版后收到此错误:
    1. 在从命令行调用程序之前,至少运行一次该程序。
    2. 检查是否正在运行单独的用户帐户。 使用提升的权限运行主用户帐户(在管理员模式下)不应导致此错误,但应确保不会意外运行 Windows 附带的内置管理员帐户。 这是一个单独的用户帐户,不会按设计显示任何已安装的 WSL 分发版。 有关详细信息,请参阅 “启用和禁用内置管理员帐户”。
    3. WSL 可执行文件仅安装到本机系统目录。 当你在 64 位 Windows 上运行 32 位进程(或在 ARM64 上运行任何非本机组合),托管的非本机进程实际上会看到不同的 System32 文件夹。 (32 位进程在 x64 Windows 上看到的路径是在 \Windows\SysWOW64 磁盘上存储的)。可以通过查看虚拟文件夹,从托管进程访问“原生”system32。 \Windows\sysnative 它实际上不会出现在磁盘上,但文件系统路径解析程序会发现它。
  • 错误:此更新仅适用于具有适用于 Linux 的 Windows 子系统的计算机。

    • 若要安装 Linux 内核更新 MSI 包,需要 WSL,并且应首先启用。 如果失败,你将看到消息: This update only applies to machines with the Windows Subsystem for Linux
    • 有三种可能的原因可以看到此消息:
    1. 你仍处于不支持 WSL 2 的旧版 Windows 中。 有关版本要求和更新链接,请参阅步骤 #2。

    2. 未启用 WSL。 需要返回到步骤 #1,并确保计算机上启用了可选的 WSL 功能。

    3. 启用 WSL 后,需要重新启动才能生效,请重新启动计算机,然后重试。

  • 错误:WSL 2 需要更新其内核组件。 有关信息,请访问 https://aka.ms/wsl2kernel

    • 如果 %SystemRoot%\system32\lxss\tools 文件夹中缺少 Linux 内核包,则会出现此错误。 通过在安装说明的步骤 4 中安装 Linux 内核更新 MSI 包来解决此问题。 可能需要从 “添加或删除程序”卸载 MSI,然后再次安装它。

常见问题

我在 Windows 10 版本 1903 上,我仍然看不到 WSL 2 的选项

这可能是因为您的计算机尚未获取 WSL 2 的补丁。 解决此问题的最简单方法是转到 Windows 设置并单击“检查更新”在系统上安装最新更新。 请参阅 有关获取回溯的完整说明

如果点击“检查更新”,但仍未收到更新,则可以 手动安装 KB KB4566116

错误:0x1bc 当 wsl --set-default-version 2

当“显示语言”或“系统区域设置”不是英语时,可能会发生这种情况。

wsl --set-default-version 2
Error: 0x1bc
For information on key differences with WSL 2 please visit https://aka.ms/wsl2

实际错误 0x1bc 为:

WSL 2 requires an update to its kernel component. For information please visit https://aka.ms/wsl2kernel

有关详细信息,请参阅问题 5749

无法访问 Windows 中的 WSL 文件

9p 协议文件服务器在 Linux 端提供服务,以允许 Windows 访问 Linux 文件系统。 如果无法在 Windows 上访问 WSL \\wsl$ ,可能是因为 9P 未正确启动。

要检查此项,可以通过 dmesg |grep 9p 查看启动日志,这会显示任何错误。 成功的输出如下所示:

[    0.363323] 9p: Installing v9fs 9p2000 file system support
[    0.363336] FS-Cache: Netfs '9p' registered for caching
[    0.398989] 9pnet: Installing 9P2000 support

有关此问题的进一步讨论,请参阅 此 GitHub 线程

无法启动 WSL 2 发行版,并且在输出中只能看到“WSL 2”

如果显示语言不是英语,则可能会看到错误文本的截断版本。

C:\Users\me>wsl
WSL 2

若要解决此问题,请访问 https://aka.ms/wsl2kernel 并按照该文档页上的说明手动安装内核。

command not found 在 Linux 中执行 Windows .exe 时

用户可以直接从 Linux 运行 windows 可执行文件,例如 notepad.exe。 有时,您可能会遇到“找不到命令”的情况,如下所示:

$ notepad.exe
-bash: notepad.exe: command not found

如果在 $PATH 中没有 Win32 路径,系统将找不到 .exe。 可以通过在 Linux 中运行 echo $PATH 来验证它。 预期会在输出中看到 Win32 路径(例如 /mnt/c/Windows)。 如果看不到任何 Windows 路径,则很可能你的 PATH 被 Linux shell 覆盖。

下面是 Debian 上的 /etc/profile 为问题做出贡献的示例:

if [ "`id -u`" -eq 0 ]; then
  PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
else
  PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
fi

Debian 的正确方法是删除上述行。 您也可以在进行以下配置时追加$PATH,但这可能导致 WSL 和 VSCode 的其他问题。

if [ "`id -u`" -eq 0 ]; then
  PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH"
else
  PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:$PATH"
fi

有关详细信息,请参阅问题 5296 和问题 5779

“错误:0x80370102无法启动虚拟机,因为未安装必需的功能。

请启用虚拟机平台 Windows 功能,并确保在 BIOS 中启用虚拟化。

  1. 检查 Hyper-V 系统要求

  2. 如果计算机是 VM,请手动启用 嵌套虚拟化 。 使用管理员启动 powershell,并运行以下命令,将其替换为 <VMName> 主机系统上虚拟机的名称(可以在 Hyper-V Manager 中找到该名称):

    Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $true
    
  3. 请按照电脑制造商关于如何启用虚拟化的指南进行作。 一般情况下,这可能需要使用系统 BIOS 来确保在 CPU 上启用这些功能。 有关此过程的说明可能因计算机而异,有关示例,请参阅 Bleeping Computer 中的本文

  4. 启用 Virtual Machine Platform 可选组件后重启计算机。

  5. 请确保在启动配置中启用了虚拟化程序。 可以通过运行(提升权限的 PowerShell)来验证这一点:

     bcdedit /enum | findstr -i hypervisorlaunchtype
    

    如果看到 hypervisorlaunchtype Off,则说明虚拟机监控程序已被禁用。 若要启用它,请在以管理员身份运行的 PowerShell 中运行:

     bcdedit /set hypervisorlaunchtype Auto
    
  6. 此外,如果安装了第三方虚拟机监控程序(例如 VMware 或 VirtualBox),请确保在支持 HyperV(VMware 15.5.5+VirtualBox 6+)的最新版本上安装了这些虚拟机监控程序,或者已关闭。

  7. 如果在 Azure 虚拟机上收到此错误,请检查以确保禁用 受信任的启动 。 Azure 虚拟机在受信任启动下不支持嵌套虚拟化。

详细了解如何在虚拟机中运行 Hyper-V 时 配置嵌套虚拟化

WSL 在工作计算机或企业环境中没有网络连接

业务或企业环境可能 已将 Windows Defender 防火墙设置配置为 阻止未经授权的网络流量。 如果 本地规则合并 设置为“否”,则默认情况下 WSL 网络将不起作用,并且管理员需要添加防火墙规则以允许它。

可以按照以下步骤确认本地规则合并设置:

Windows 防火墙设置屏幕截图

  1. 打开“具有高级安全性的 Windows Defender 防火墙” (这与控制面板中的“Windows Defender 防火墙”不同)
  2. 右键单击“本地计算机上具有高级安全性的 Windows Defender 防火墙”选项卡
  3. 选择“属性”
  4. 选择打开的新窗口中的“公共配置文件”选项卡
  5. 在“设置”部分下选择“自定义”
  6. 在打开的“自定义公共配置文件的设置”窗口中检查“规则合并”是否设置为“否”。 这会阻止访问 WSL。

可以在 “配置 Hyper-V 防火墙”中找到有关如何更改此防火墙设置的说明。

WSL 连接到 VPN 后没有网络连接

如果在 Windows 上连接到 VPN 后,bash 会失去网络连接,请尝试在 bash 中解决此问题。 此解决方法允许你通过手动方式替代 DNS 解析 /etc/resolv.conf

  1. 记下从 ipconfig.exe /all 中获取的 VPN 的 DNS 服务器。
  2. 创建现有 resolv.conf 的副本 sudo cp /etc/resolv.conf /etc/resolv.conf.new
  3. 解除当前 resolv.conf sudo unlink /etc/resolv.conf 的链接
  4. sudo mv /etc/resolv.conf.new /etc/resolv.conf
  5. 编辑 /etc/wsl.conf 此内容并将其添加到文件。 (有关此设置的详细信息,请参阅 高级设置配置
[network]
generateResolvConf=false
  1. 打开 /etc/resolv.conf
    a。 从包含描述自动生成的注释的文件中删除第一行
    b. 将上面的 DNS 条目添加为 DNS 服务器列表中的第一个条目。
    选项c. 关闭 文件。

断开 VPN 连接后,必须将更改还原为 /etc/resolv.conf。 为此,您可以执行以下步骤:

  1. cd /etc
  2. sudo mv resolv.conf resolv.conf.new
  3. sudo ln -s ../run/resolvconf/resolv.conf resolv.conf

WSL 的全局安全访问客户端问题

全局安全访问客户端(/entra/global-secure-access/how-to-install-windows-client)可能会影响 WSL 连接,因为它具有在解析名称时返回临时地址的功能。 然后在建立网络连接时将地址替换为实际地址。 这可能会破坏 WSL,因为 WSL 流量被转发到大量 GSA 客户端挂钩的以下层。

建议禁用 DNS 隧道(dnsTunneling=false)或禁用镜像模式(networkingMode=nat)。

Cisco Anyconnect VPN 在 WSL 的 NAT 模式下存在问题

Cisco AnyConnect VPN 以阻止 NAT 工作的方式修改路由。 有一种特定于 WSL 2 的解决方法:请参阅 Cisco AnyConnect 安全移动性客户端管理员指南(版本 4.10 - AnyConnect 疑难解答)。

镜像网络模式处于打开状态时 VPN 的 WSL 连接问题

镜像网络模式目前是 WSL 配置中的实验性设置。 WSL 的传统 NAT 网络体系结构可以更新为名为“镜像网络模式”的全新网络模式。 当实验networkingMode设置为mirrored后,Windows 上已有的网络接口将被映射到 Linux 以提高兼容性。 在命令行博客中了解详细信息: WSL 2023 年 9 月更新

已测试并确认某些 VPN 与 WSL 不兼容,包括:

  • “Bitdefender”版本 26.0.2.1
  • “OpenVPN”版本 2.6.501
  • “Mcafee Safe Connect”版本 2.16.1.124

在 WSL 中对 HttpProxy 镜像使用 autoProxy 时的注意事项

可以在 autoProxy中使用 设置来配置 HTTP/S 代理镜像。 应用此设置时,请注意以下注意事项:

  • PAC 代理:WSL 将通过设置“WSL_PAC_URL”环境变量在 Linux 中配置设置。 默认情况下,Linux 不支持 PAC 代理。
  • 与 WSLENV 的交互:用户定义的环境变量优先于此功能指定的环境变量。

启用后,以下项适用于 Linux 分发版上的代理设置:

  • Linux 环境变量 HTTP_PROXY设置为在 Windows HTTP 代理配置中安装的一个或多个 HTTP 代理。
  • Linux 环境变量 HTTPS_PROXY设置为在 Windows HTTP 代理配置中安装的一个或多个 HTTPS 代理。
  • Linux 环境变量 NO_PROXY设置为绕过在 Windows 配置目标中找到的任何 HTTP/S 代理。
  • 每个环境变量(除外 WSL_PAC_URL)都设置为小写和大写。 例如:HTTP_PROXYhttp_proxy

ZScaler 配置导致已知问题,其中 ZScaler 重复启用和禁用 Windows 代理配置,导致 WSL 反复显示“主机上检测到 Http 代理更改”通知。

在命令行博客中了解详细信息: WSL 2023 年 9 月更新

DNS 隧道中的网络考量因素

当 WSL 无法连接到 Internet 时,可能是因为对 Windows 主机的 DNS 调用被阻止。 这是因为现有网络配置阻止了 WSL VM 发送到 Windows 主机的 DNS 的网络数据包。 DNS 隧道修复了此问题,方法是使用虚拟化功能直接与 Windows 通信,从而允许解析 DNS 名称,而无需发送网络数据包。 此功能应提高网络兼容性,并允许你获得更好的 Internet 连接,即使你拥有 VPN、特定的防火墙设置或其他网络配置。

可以使用 dnsTunneling 设置在 WSL 配置文件实验部分中配置 DNS 隧道。 应用此设置时,请注意以下注意事项:

  • 如果将 VPN 与 WSL 配合使用,请启用 DNS 隧道。 许多 VPN 使用 NRPT 策略,这些策略仅在启用 DNS 隧道时应用于 WSL DNS 查询。
  • /etc/resolv.conf Linux 分发中的文件有 3 个 DNS 服务器的最大限制,而 Windows 可能使用 3 个以上的 DNS 服务器。 使用 DNS 隧道可消除此限制 - Linux 现在可以使用所有 Windows DNS 服务器。
  • WSL 将按以下顺序使用 Windows DNS 后缀(类似于 Windows DNS 客户端使用的顺序):
    1. 全局 DNS 后缀
    2. 补充 DNS 后缀
    3. 接口专用 DNS 后缀
    4. 如果在 Windows 上启用了 DNS 加密(DoH、DoT),加密将应用于 WSL 中的 DNS 查询。 如果用户想要在 Linux 中启用 DoH、DoT,则需要禁用 DNS 隧道。
  • 来自 Docker Desktop 管理的 Docker 容器的 DNS 查询将绕过 DNS 隧道。 Docker Desktop 采用自己的方式(不同于 DNS 隧道),用于将主机 DNS 设置和策略应用到 Docker 容器中的 DNS 查询。
  • 若要成功启用 DNS 隧道,不应禁用 wsl.conf 文件中的 generateResolvConf 选项。
  • 启用 DNS 隧道后,将忽略 wsl.conf 文件中的 generateHosts 选项(Windows DNS 主机文件未在 Linux /etc/hosts 文件中复制)。 Windows 主机文件中的策略将应用于 Linux 中的 DNS 查询,而无需在 Linux 中复制该文件。

在命令行博客中了解详细信息: WSL 2023 年 9 月更新

指导 Windows 主机收到的入站流量到 WSL 虚拟机的问题

使用镜像网络模式(实验性功能 networkingMode 设置为 mirrored),Windows 主机接收到的某些入站流量将不会被传递到 Linux 虚拟机。 此流量如下所示:

  • UDP 端口 68 (DHCP)
  • TCP 端口 135 (DCE 终结点解析)
  • TCP 端口 1900 (UPnP)
  • TCP 端口 2869 (SSDP)
  • TCP 端口 5004 (RTP)
  • TCP 端口 3702 (WSD)
  • TCP 端口 5357 (WSD)
  • TCP 端口 5358 (WSD)

使用镜像网络模式时,WSL 将自动配置某些 Linux 网络设置。 不支持使用镜像网络模式时这些设置的任何用户配置。 下面是 WSL 将配置的设置列表:

设置名称 价值
https://sysctl-explorer.net/net/ipv4/accept_local/ 已启用 (1)
https://sysctl-explorer.net/net/ipv4/route_localnet/ 已启用 (1)
https://sysctl-explorer.net/net/ipv4/rp_filter/ 已禁用 (0)
https://sysctl-explorer.net/net/ipv6/accept_ra/ 已禁用 (0)
https://sysctl-explorer.net/net/ipv6/autoconf/ 已禁用 (0)
https://sysctl-explorer.net/net/ipv6/use_tempaddr/ 已禁用 (0)
地址生成模式 已禁用 (0)
disable_ipv6(禁用IPv6) 已禁用 (0)
https://sysctl-explorer.net/net/ipv4/arp_filter/ 已启用 (1)

在默认网络命名空间下运行时启用镜像网络模式的 WSL2 中的 Docker 容器问题

存在一个已知问题,即无法创建具有已发布端口的 Docker 桌面容器(docker run –publish/-p)。 WSL 团队正在与 Docker 桌面团队合作解决此问题。 若要解决此问题,请使用 Docker 容器中的主机网络命名空间。 通过“docker run”命令中使用的“--network host”选项设置网络类型。 另一种解决方法是在 ignoredPorts的设置中列出已发布的端口号。

当其网络管理器正在运行时,Docker 容器出现问题

Docker 容器运行网络管理器服务时存在已知问题。 症状包括尝试与主机建立环回连接时失败。 建议停止网络管理器服务,以便正确配置 WSL 网络。

sudo systemctl disable network-manager.service

解析 WSL 中的 .local 名称

若要将主机名解析为本地网络中的 IP 地址,无需使用传统的 DNS 服务器,通常使用 .local 名称。 这是通过 mDNS(多播 DNS)协议实现的,该协议依赖于多播流量来运行。

networkingMode 设置为 NAT:

目前,启用 DNS 隧道时不支持此功能。 若要启用 .local 名称的解析,建议使用以下解决方案:

  • 禁用 DNS 隧道。
  • 使用镜像网络模式。

networkingMode 设置为 Mirrored:

注意:您需要在 WSL 版本 2.3.17 或更高版本上,以便使用以下功能。

由于镜像模式支持多播流量,因此 mDNS(多播 DNS)协议可用于解析 .local 名称。 Linux 必须配置为支持 mDNS,因为它默认不这样做。 配置它的一种方法是使用以下两个步骤:

  1. 安装“libnss-mdns”包
sudo apt-get install libnss-mdns

*“libnss-mdns”包是 GNU C 库 (glibc) 的 GNU 名称服务交换机 (NSS) 功能的插件,它通过多播 DNS (mDNS) 提供主机名解析。 此包实际上允许常见的 Unix/Linux 程序解析临时 mDNS 域 .local 中的名称。

  1. /etc/nsswitch.conf 文件配置为在“hosts”部分中启用“mdns_minimal”设置。 文件的示例内容:
cat /etc/nsswitch.conf
# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

passwd:         compat systemd
group:          compat systemd
shadow:         compat
gshadow:        files

hosts:          files mdns_minimal [NOTFOUND=return] dns
networks:       files

protocols:      db files
services:       db files
ethers:         db files
rpc:            db files

netgroup:       nis

WSL 中的 DNS 后缀

根据 .wslconfig 文件中的配置,WSL 在 DNS 后缀方面将有以下行为:

当 networkingMode 设置为 NAT 时:

案例 1) 默认情况下,Linux 中未配置 DNS 后缀

案例 2) 如果启用 DNS 隧道(在 .wslconfig 中将 dnsTunneling 设置为 true),则会在 Linux 中配置所有 Windows DNS 后缀,在 /etc/resolv.conf 的“搜索”设置中配置

后缀按以下顺序在 /etc/resolv.conf 中配置,类似于 Windows DNS 客户端在解析名称时尝试后缀的顺序:首先全局 DNS 后缀,然后补充 DNS 后缀,然后按接口 DNS 后缀。

当 Windows DNS 后缀发生更改时,该更改将自动反映在 Linux 中

案例 3) 如果禁用 DNS 隧道并且禁用了 SharedAccess DNS 代理(dnsTunneling 设置为 false,而 dnsProxy 在 .wslconfig 中设置为 false),则 Linux 中配置了单个 DNS 后缀,在 /etc/resolv.conf 的“域”设置中配置

当 Windows DNS 后缀发生更改时,该更改不会反映在 Linux 中

Linux 中配置的单个 DNS 后缀是从每个接口 DNS 后缀中选择的(忽略全局和补充后缀)

如果 Windows 具有多个接口,则会使用启发式选择将在 Linux 中配置的单个 DNS 后缀。 例如,如果 Windows 上有 VPN 接口,则从该接口中选择后缀。 如果没有 VPN 接口,则从最有可能提供 Internet 连接的接口中选择后缀。

当 networkingMode 设置为 Mirrored 时:

所有 Windows DNS 后缀都配置在 Linux 中,在 /etc/resolv.conf 的“搜索”设置中

后缀在 /etc/resolv.conf 中按与 NAT 模式的第2种情况相同的顺序进行配置。

当 Windows DNS 后缀发生更改时,该更改将自动反映在 Linux 中

注意:可以使用 SetInterfaceDnsSettings - Win32 应用 | Microsoft Learn 在 Windows 中配置补充 DNS 后缀,并在 Settings 参数中设置标志 DNS_SETTING_SUPPLEMENTAL_SEARCH_LIST

排查 WSL 中的 DNS 问题

当 WSL 在 NAT 模式下启动容器时的默认 DNS 配置是让 Windows 主机上的 NAT 设备充当 WSL 容器的 DNS“服务器”。 当 DNS 查询从 WSL 容器发送到 Windows 主机上的 NAT 设备时,DNS 数据包将从 NAT 设备转发到主机上的共享访问服务;响应以反向方向发送回 WSL 容器。 为使数据包转发过程到共享访问正常进行,防火墙规则需要允许入站的 DNS 数据包。该数据包是在 WSL 最初请求 HNS 为其 WSL 容器创建 NAT 虚拟网络时,由 HNS 服务创建的。

由于这种 NAT - 共享访问设计,有几个已知的配置可能会破坏 WSL 的名称解析。

1.企业可以推送不允许本地定义的防火墙规则的策略,只允许企业策略定义的规则。

如果这是企业设置的,则忽略 HNS 创建的防火墙规则,因为它是本地定义的规则。 若要使此配置正常工作,企业必须创建防火墙规则,以允许 UDP 端口 53 到共享访问服务,或者 WSL 可以设置为使用 DNS 隧道。 可以通过运行以下内容来查看这是否配置为不允许本地定义的防火墙规则。 请注意,这将显示所有 3 个配置文件的设置:域、专用和公用。 如果已在任何配置文件上设置,则如果为 WSL vNIC 分配该配置文件(默认值为 Public),则会阻止数据包。 这只是 Powershell 中返回的第一个防火墙配置文件的代码片段:

PS C:\> Get-NetFirewallProfile -PolicyStore ActiveStore
Name                            : Domain
Enabled                         : True
DefaultInboundAction            : Block
DefaultOutboundAction           : Allow
AllowInboundRules               : True
AllowLocalFirewallRules         : False

AllowLocalFirewallRules:False means the locally defined firewall rules, like that by HNS, will not be applied or used.

2. 企业可以应用组策略和 MDM 策略配置来阻止所有传入规则。

这些设置将优先于任何 Allow-Inbound 防火墙规则。 因此,此设置将阻止 HNS 创建的 UDP 防火墙规则,从而阻止 WSL 解析名称。 要使此配置正常工作, 必须将 WSL 设置为使用 DNS 隧道。 此设置将始终阻止 NAT DNS 代理。

从组策略:

计算机配置 \ 管理模板 \ 网络 \ 网络连接 \ Windows Defender 防火墙 \ 域配置文件 |标准配置文件

“Windows Defender 防火墙:不允许例外”- 已启用

MDM 策略来源:

./Vendor/MSFT/Firewall/MdmStore/PrivateProfile/Shielded

./Vendor/MSFT/Firewall/MdmStore/DomainProfile/Shielded

./Vendor/MSFT/Firewall/MdmStore/PublicProfile/Shielded

可以通过运行以下命令来查看是否已配置为不允许任何入站防火墙规则(请参阅上述防火墙配置文件的注意事项)。 这只是 Powershell 中返回的第一个防火墙配置文件的代码片段:


PS C:\> Get-NetFirewallProfile -PolicyStore ActiveStore
Name                            : Domain
Enabled                         : True
DefaultInboundAction            : Block
DefaultOutboundAction           : Allow
AllowInboundRules               : False

AllowInboundRules: False means that no inbound Firewall rules will be applied.

3. 用户在 Windows 安全设置应用中检查设置,确认是否“阻止所有传入连接,包括允许的应用列表中的连接”。

Windows 支持用户选择加入上述 #2 中引用的企业可应用的相同设置。 用户可以打开“Windows 安全性”设置页,选择“防火墙和网络保护”选项,选择要配置的防火墙配置文件(域、专用或公共),并在“传入连接”下检查标记为“阻止所有传入连接(包括允许的应用列表中的连接)”的控制。

如果为公共配置文件设置了此设置(这是 WSL vNIC 的默认配置文件),则 HNS 创建的防火墙规则将阻止 UDP 数据包进行共享访问。

为让 NAT DNS 代理配置在使用 WSL 时有效,必须取消选中此项,或者将 WSL 设置为使用 DNS 隧道。

4.允许 DNS 数据包共享访问的 HNS 防火墙规则可能无效,引用以前的 WSL 接口标识符。 这是 HNS 中已修复的最新 Windows 11 版本的缺陷。 在早期版本中,如果发生这种情况,则不容易发现,但它有一个简单的解决方法:

  • 停止 WSL

    wsl.exe –shutdown

  • 删除旧的 HNS 防火墙规则。 在大多数情况下,此 Powershell 命令应正常工作:

    Get-NetFirewallRule -Name "HNS*" | Get-NetFirewallPortFilter | where Protocol -eq UDP | where LocalPort -eq 53 | Remove-NetFirewallRule

  • 删除所有 HNS 终结点。 注意:如果使用 HNS 管理其他容器(如 MDAG 或 Windows 沙盒),则还应停止这些容器。

    hnsdiag.exe delete all

  • 重新启动或重启 HNS 服务

    Restart-Service hns

  • 重启 WSL 后,HNS 将创建新的防火墙规则,正确针对 WSL 接口。

排查 Windows 上的网络访问问题

如果没有网络访问权限,则可能是因为配置错误。 请查看 FSE 驱动程序是否正在运行:“sc queryex FSE”。 如果未显示 FSE 正在运行,请检查此注册表项下是否存在 PortTrackerEnabledMode 注册表值:reg query HKLM\System\CurrentControlSet\Services\Tcpip\Parameters。 如果 FSE 未运行或安装,并且 PortTrackerEnabledMode 存在,请删除该注册表值并重新启动

手动删除虚拟适配器的方法

虚影适配器,或虚拟即插即用(PnP)设备,指显示在系统中但未物理连接的硬件组件。 这些“幽灵”设备可能会导致系统设置中的混乱和杂乱。 如果在虚拟机(VM)中运行 WSL 时看到虚影适配器,请按照以下手动步骤查找和删除这些虚拟 PnP 设备。 Microsoft正在处理不需要手动干预的自动化解决方案。 更多信息即将推出。

  1. 打开“设备管理器”
  2. 查看 > 显示隐藏的设备

“设备管理器显示隐藏的设备”菜单的屏幕截图

  1. 打开网络适配器

网络适配器列表的屏幕截图

  1. 右键单击虚影网络适配器并选择“ 卸载设备”

右键单击网络列表中的虚拟 pnp 并选择卸载设备的屏幕截图

启动 WSL 或安装分发版将返回错误代码

按照说明在 GitHub 上的 WSL 存储库中收集 WSL 日志 ,以收集详细的日志并在 GitHub 上提出问题。

更新 WSL

适用于 Linux 的 Windows 子系统有两个组件,可能需要更新。

  1. 若要更新适用于 Linux 的 Windows 子系统本身,请使用 PowerShell 或 CMD 中的命令 wsl --update

  2. 若要更新特定的 Linux 分发用户二进制文件,请使用以下命令: apt-get update | apt-get upgrade 在要更新的 Linux 分发版中。

通过 Apt-get 升级时发生的错误

某些包使用尚未实现的功能。 例如,udev 目前尚不支持,并导致多个 apt-get upgrade 错误。

若要修复与 udev此问题相关的问题,请执行以下步骤:

  1. 将以下内容 /usr/sbin/policy-rc.d 写入并保存所做的更改。

    #!/bin/sh
    exit 101
    
  2. 将执行权限添加到 /usr/sbin/policy-rc.d

    chmod +x /usr/sbin/policy-rc.d
    
  3. 运行以下命令:

    dpkg-divert --local --rename --add /sbin/initctl
    ln -s /bin/true /sbin/initctl
    

安装时出现“错误:0x80040306”

这与我们不支持旧版控制台这一事实有关。 若要关闭旧版控制台,请执行以下作:

  1. 打开 cmd.exe
  2. 右键单击标题栏 - 属性 ->> 取消选中“使用旧版控制台”
  3. 单击“确定”

Windows 更新后出现“错误:0x80040154”

Windows Update 期间可能会禁用适用于 Linux 的 Windows 子系统功能。 如果发生这种情况,则必须重新启用 Windows 功能。 有关启用适用于 Linux 的 Windows 子系统的说明,请参阅 手动安装指南

更改显示语言

WSL 安装将尝试自动更改 Ubuntu 区域设置以匹配 Windows 安装的区域设置。 如果不希望此行为,可以在安装完成后运行此命令来更改 Ubuntu 区域设置。 必须重新启动 bash.exe 才能使此更改生效。

以下示例将区域设置更改为en-US

sudo update-locale LANG=en_US.UTF8

Windows 系统还原后的安装问题

  1. 删除 %windir%\System32\Tasks\Microsoft\Windows\Windows Subsystem for Linux 文件夹。
    注意:如果可选功能已完全安装且正常工作,请不要执行此作。
  2. 启用 WSL 可选功能(如果尚未启用)
  3. 重新启动
  4. 此命令用于完全卸载 lxrun 环境:lxrun /uninstall /full
  5. 安装 bash

WSL 中无法连接到互联网

某些用户报告了特定防火墙应用程序阻止 WSL 中的 Internet 访问的问题。 报告的防火墙包括:

  1. 卡巴斯基
  2. AVG
  3. Avast
  4. Symantec Endpoint Protection

在某些情况下,关闭防火墙允许访问。 在某些情况下,只需安装防火墙即可阻止访问。

如果你正在使用 Microsoft Defender 防火墙,取消选中“阻止所有传入连接,包括允许的应用列表中的连接”选项,即可允许访问。

使用 ping 时出现权限被拒绝的错误

Windows 周年更新 1607 版本中,要在 WSL 中运行 ping,您需要具有管理员权限。 若要运行 ping,请以管理员身份在 Windows 上的 Ubuntu 上运行 Bash,或者从具有管理员权限的 CMD/PowerShell 提示符运行 bash.exe。

对于更高版本的 Windows( 内部版本 14926+),不再需要管理员权限。

Bash 挂起

如果在使用 bash 时,你发现 bash 卡住(或发生死锁),并且不响应输入,请通过收集并报告内存转储来帮助我们诊断问题。 请注意,这些步骤会使系统崩溃。 如果你对此不感到舒服,或在这样做之前没有保存你的工作,请不要这样做。

收集内存转储

  1. 将内存转储类型更改为“完整内存转储”。 更改转储类型时,请记下当前类型。

  2. 使用 步骤通过键盘控件设置崩溃管理。

  3. 重新设置挂起或死锁。

  4. 用按键序列(2)中的键使系统崩溃。

  5. 系统将崩溃并收集内存转储。

  6. 系统重新启动后,将memory.dmp报告给 secure@microsoft.com。 转储文件的默认位置 %SystemRoot%\memory.dmp 或 C:\Windows\memory.dmp(如果 C: 是系统驱动器)。 在电子邮件中,请注明该转储是给 WSL 或 Bash on Windows 团队的。

  7. 将内存转储类型还原到原始设置。

检查版本号

若要查找电脑的体系结构和 Windows 内部版本号,请打开
设置>系统>关于

查找 “OS 生成 ”和 “系统类型” 字段。
“生成”和“系统类型”字段的屏幕截图

若要查找 Windows Server 内部版本号,请在 PowerShell 中运行以下命令:

systeminfo | Select-String "^OS Name","^OS Version"

确认已启用 WSL

可以通过在提升的 PowerShell 窗口中运行以下命令来确认已启用适用于 Linux 的 Windows 子系统:

Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

OpenSSH-Server 连接问题

尝试连接 SSH 服务器时失败,出现以下错误:“连接被 127.0.0.1 端口 22 关闭”。

  1. 确保 OpenSSH 服务器正在运行:

    sudo service ssh status
    

    你已遵循本教程进行操作:https://ubuntu.com/server/docs/service-openssh

  2. 停止 sshd 服务并在调试模式下启动 sshd:

    sudo service ssh stop
    sudo /usr/sbin/sshd -d
    
  3. 检查启动日志并确保 HostKey 可用,并且看不到日志消息,例如:

    debug1: sshd version OpenSSH_7.2, OpenSSL 1.0.2g  1 Mar 2016
    debug1: key_load_private: incorrect passphrase supplied to decrypt private key
    debug1: key_load_public: No such file or directory
    Could not load host key: /etc/ssh/ssh_host_rsa_key
    debug1: key_load_private: No such file or directory
    debug1: key_load_public: No such file or directory
    Could not load host key: /etc/ssh/ssh_host_dsa_key
    debug1: key_load_private: No such file or directory
    debug1: key_load_public: No such file or directory
    Could not load host key: /etc/ssh/ssh_host_ecdsa_key
    debug1: key_load_private: No such file or directory
    debug1: key_load_public: No such file or directory
    Could not load host key: /etc/ssh/ssh_host_ed25519_key
    

如果看到此类消息且/etc/ssh/下的密钥缺失,则您必须重新生成密钥,或者仅清除并安装openssh-server。

sudo apt-get purge openssh-server
sudo apt-get install openssh-server

“找不到引用的程序集。”启用 WSL 可选功能时

此错误与处于错误安装状态有关。 请完成以下步骤来尝试并解决此问题:

  • 如果您在 PowerShell 中运行启用 WSL 功能的命令,可以尝试使用图形界面。在开始菜单中搜索“打开或关闭 Windows 功能”,然后在列表中选择“适用于 Linux 的 Windows 子系统”,以进行可选组件的安装。

  • 转到“设置”、“更新”并单击“检查更新”来更新 Windows 版本

  • 如果这两个都失败,并且你需要访问 WSL,请考虑使用安装媒体重新安装 Windows,然后选择“保留所有内容”以确保你的应用和文件保持原样。 可以在 “重新安装 Windows 10”页面上找到有关如何执行此作的说明。

如果看到此错误:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0777 for '/home/user/.ssh/private-key.pem' are too open.

若要解决此问题,请将以下内容追加到 /etc/wsl.conf 该文件:

[automount]
enabled = true
options = metadata,uid=1000,gid=1000,umask=0022

请注意,添加此命令将包括元数据,并修改从 WSL 看到的 Windows 文件的文件权限。 有关详细信息,请参阅 文件系统权限

无法通过 Windows 上的 OpenSSH 远程使用 WSL

如果在 Windows 上使用 openssh-server 并尝试远程访问 WSL,则许多人会看到此错误:

The file cannot be accessed by the system.

使用 WSL 的应用商店版本时,这是一个 已知问题。 可以使用 WSL 1 或 Windows 中的 WSL 版本解决此问题。 有关详细信息,请参阅 https://aka.ms/wslstoreinfo

运行 Windows 命令在分发版中失败

某些Microsoft应用商店中提供的分发版尚未开箱即用地运行 Windows 命令。 如果在运行-bash: powershell.exe: command not found或任何其他 Windows 命令时遇到错误powershell.exe /c start .,您可以按照以下步骤解决此错误:

  1. 在 WSL 分发版中运行 echo $PATH
    如果不包含:/mnt/c/Windows/system32,那么某些东西正在重新定义标准 PATH 变量。
  2. 使用cat /etc/profile检查配置文件设置。
    如果它包含 PATH 变量的赋值,请编辑该文件以注释掉带 # 字符的 PATH 赋值块。
  3. 检查 wsl.conf 是否存在 cat /etc/wsl.conf 并确保它不包含 appendWindowsPath=false,否则将其注释掉。
  4. 通过键入 wsl -t 后跟分发名称或在 cmd 或 PowerShell 中运行 wsl --shutdown 来重启分发。

安装 WSL 2 后无法启动

我们注意到了影响用户在安装 WSL 2 后无法启动的问题。 在我们对这些问题进行全面诊断的同时,用户报告称,更改缓冲区大小安装正确的驱动程序可以帮助解决此问题。 请查看此 GitHub 问题 ,查看此问题的最新更新。

禁用 ICS 时出现 WSL 2 错误

Internet 连接共享(ICS)是 WSL 2 的必需组件。 主机网络服务 (HNS) 使用 ICS 服务创建 WSL 2 依赖的 NAT、DNS、DHCP 和主机连接共享的基础虚拟网络。

禁用 ICS 服务(SharedAccess)或通过组策略禁用 ICS 将阻止创建 WSL HNS 网络。 这将导致创建新的 WSL 版本 2 映像时失败,尝试将版本 1 映像转换为版本 2 时出现以下错误。

There are no more endpoints available from the endpoint mapper.

需要 WSL 2 的系统应将 ICS 服务(SharedAccess)保留为默认启动状态、手动(触发器启动)以及禁用 ICS 的任何策略都应被覆盖或删除。 禁用 ICS 服务会导致 WSL 2 出现问题,因此我们不建议禁用 ICS。不过,您可以使用这些说明来禁用 ICS 的某些功能。

使用较旧版本的 Windows 和 WSL

如果运行的是较旧版本的 Windows 和 WSL,如 Windows 10 创意者更新(2017 年 10 月版本 16299)或周年更新(2016 年 8 月版本 14393),则有几个区别需要注意。 我们建议 你更新到最新的 Windows 版本,但如果这是不可能的,我们概述了以下一些差异。

互作性命令差异:

  • bash.exe 已替换为 wsl.exe。 Linux 命令可以从 Windows 命令提示符或 PowerShell 运行,但对于早期 Windows 版本,可能需要使用此命令 bash 。 例如: C:\temp> bash -c "ls -la"。 传入 bash -c 的 WSL 命令将转发到 WSL 进程,而无需修改。 文件路径必须以 WSL 格式指定,并且需要仔细注意转义相关字符。 例如:C:\temp> bash -c "ls -la /proc/cpuinfo"C:\temp> bash -c "ls -la \"/mnt/c/Program Files\""
  • 若要查看哪些命令可用于特定分发版,请运行 [distro.exe] /?。 例如,使用 Ubuntu: C:\> ubuntu.exe /?
  • Windows 路径包含在 WSL $PATH中。
  • 在早期版本的 Windows 10 中从 WSL 分发版调用 Windows 工具时,需要指定目录路径。 例如,若要从 WSL 命令行调用 Windows 记事本应用,请输入: /mnt/c/Windows/System32/notepad.exe
  • 若要更改默认用户以 root 在 PowerShell 中使用此命令: C:\> lxrun /setdefaultuser root 然后运行 Bash.exe 以登录: C:\> bash.exe。 使用分发密码命令重置密码: $ passwd username 然后关闭 Linux 命令行: $ exit。 在 Windows 命令提示符或 Powershell 中,将默认用户重置回正常的 Linux 用户帐户: C:\> lxrun.exe /setdefaultuser username

卸载旧版 WSL

如果最初在创意者更新之前的 Windows 10 版本(2017 年 10 月内部版本 16299)上安装 WSL,建议将任何必要的文件、数据等从安装的较旧的 Linux 分发版迁移到通过 Microsoft 应用商店安装的较新的分发版。 若要从计算机中删除旧分发版,请从命令行或 PowerShell 实例运行以下命令: wsl --unregister Legacy 您还可以选择使用 Windows 文件资源管理器或 PowerShell,手动删除旧版遗留发行版的 %localappdata%\lxss\ 文件夹及其所有子内容。rm -Recurse $env:localappdata/lxss/