我有一台安装了 WSL2 的 Windows 10。在 WSL2 中我有一个 Ubuntu。我需要直接从 Ubuntu 使用物理 PC 中的不同适配器,并可以从 Windows 访问它们。但在 WSL2 中我只有一个虚拟适配器。运行时看不到其他适配器ifconfig -a
。有没有办法让 Ubuntu 中的所有 Windows 网络适配器都可用/可见?
使用案例:我的 PC 上有许多适配器,这些适配器物理连接到不同的设备。我需要向这些设备发送信号(请求)。
答案1
从 WSL2 2.0.0 版开始,有两种单独的网络模式可用。这个问题中提到的用例现在最好使用新的“镜像”网络模式来处理。
镜像模式
笔记:
适用于 Windows 11 23H2 和 WSL2 2.0.0 及更高版本*
从@KenvixZure在评论中:
镜像模式仍存在许多问题。如果您的应用程序在 NAT 模式下运行良好,请不要更改它。
这是很好的建议,值得赞赏。镜像模式是 WSL2 的一个相对较新的功能,虽然我个人没有直接遇到过问题,但预计会有一些问题需要解决。
在镜像模式下,Windows 的网络接口被镜像到 WSL2,允许再次单独处理它们,类似于(但比 WSL1 中的方式有所改进)(如下所述)。启用此模式后,现在应该完全可以与连接到 Windows 主机中不同 NIC 的本地网络上的设备进行通信。
要启用镜像模式:
将以下内容添加到您的
<windows_user_profile>/.wslconfig
:[wsl2] networkingMode=mirrored
退出 WSL 发行版
从 PowerShell运行
wsl --shutdown
然后重新启动 WSL
正在运行ip addr
,ip link
现在应该向您显示 Windows 的所有物理接口(以及一些虚拟接口),并能够根据需要在它们之间进行路由。
请注意,在此模式下,Windows 中的 WiFi 接口将出现在有线 NIC 上。可能存在其他一些限制,但您至少可以在 WSL2 中打开和关闭这些接口(与下面提到的 WSL1 不同)。
NAT组网模式
这是这个问题的原始答案。它仍然适用于默认的 NAT 网络模式。如果您使用的是旧版本的 Windows 和/或 WSL,那么您肯定会处于此模式。
正如你所见,WSL1 为你提供了 Windows 接口到“Linux 接口”的更好的映射,但了解 WSL1 和 WSL2 在这方面的差异很重要:
在 WSL1 下,当 Linux 应用调用 Linux API 时,WSL1 负责尝试将其映射到 Windows API。因此,当
ifconfig
(或ip
)尝试调用获取地址要获取可用的接口,WSL1 会弹出列表视窗内核知道。另一方面,WSL2 在虚拟化环境(Hyper-V 的一个子集)中运行真正的 Linux 内核。其中
getifaddrs
列举了虚拟机向 Linux 内核提供的接口。
两者各有优缺点:
WSL1 中最大的问题是,使用这些接口可以做的事情非常有限。微软的 Windows->Linux API 映射在硬件方面只能做到如此深入。
例如,即使是一个非常基本的诸如打开或关闭接口之类的任务不会起作用。例如
sudo ip link set wifi0 down
将始终返回RTNETLINK answers: Operation not permitted
。您无法将接口置于混杂模式、运行 WireShark 或类似操作。当然,WSL2 的虚拟化意味着您在调用 Linux 命令时甚至看不到 Windows 接口。另一方面,您可以完全访问虚拟接口。
那里可能根据您的用例,WSL2 可能对您有所帮助。您提到安装了多个接口,每个接口都连接到不同的端点设备。
如果对您有用,最简单的方案就是为 Windows 中的每个接口分配一个不同的子网,并依靠 Windows 路由表根据设备的 IP 地址处理数据包。WSL2 中的虚拟接口应该“正常工作”,并将数据包发送到 Windows 主机进行正确的路由。
如果这不起作用,请查看socat
其他选项。有一个 Windows 版本可用(虽然我还没有尝试过),以及大多数发行版中都有的标准 Linux 版本。我已经成功在 WSL2 中创建了映射到其他端点的 TAP/TUN 设备,尽管我已经有一段时间没有这样做了,而且我记不太清细节了。理论上,你可以在socat
WSL2 上运行的程序包和 Windows 主机本身上运行的程序包之间进行混排,以满足更复杂的用例。
虽然这不是您用例的一部分,但我会向其他可能阅读此内容的人提及这一点,因为它与问题相关。如果您出于某种原因需要在 WSL(1 或 2)内执行启用或禁用 Windows 界面之类的操作,请考虑通过 调用powershell.exe
。例如:
powershell.exe -c "Disable-NetAdapter -name 'Wi-Fi'"
请注意,这需要在 UAC 提升的终端中完成,因为 WSL 无法执行 Windows 用户无法执行的任何操作(即使以 root 身份执行)。另请注意,在 UAC 提升的会话中,您可能需要指定 的完整路径powershell.exe
。
最后,我之所以这么说,只是因为我最近看到一些人批评 WSL 的局限性,但我不认为这是 WSL 的局限性。如果在 VMWare、VirtualBox 或任何其他虚拟化环境下运行,您会遇到与虚拟接口相同的问题。恕我直言,与其他虚拟化环境相比,WSL 为我们提供了更多选项来尝试解决这个问题。
答案2
否定回答:在 WSL2 中不可能,您需要继续使用 WSL1。
WSL2 本质上是在 Hyper-V 虚拟机内运行的。与所有虚拟机一样,它的网络接口也是虚拟的。
因此,WSL2 看不到您的网卡。相反,您有一个虚拟以太网设备。这是因为 WSL2 实际上是为在 Windows 上运行和开发 Linux 应用程序而设计的,而不是为访问物理硬件而设计的。
如果您确实需要使用物理硬件,则需要直接在 Windows 上使用 Windows 程序,或者在真实硬件上以双启动方式安装真正的 Linux 发行版。
您最多可以将 WSL2 虚拟网络适配器从 NAT 切换到 Bridged。这将使您能够更好地访问网络,尽管仍然是同一个虚拟适配器。(有关此操作,请参阅 关联)。
答案3
将 WSL 版本降级到 1.0 有助于在 Ubuntu 中获得相同的适配器。如果有办法在 2.0 版本中实现它,请添加评论
答案4
对于较旧的 Windows/WSL2 版本,我创建了一个用于导出任何网络适配器的工具。已发布这里
简而言之 - AF_HYPERV/AF_VSOCK 用于主机和客户机之间的通信。Npcap 用于在主机上捕获/注入真实接口上的数据包。在客户机端 - tuntap 模式 tap 适配器用于在内核堆栈中捕获/注入数据包。
我当前使用的设置是:
- Dell R220 上的 Broadcom BCM5720。访问 VLAN123 并标记 VLAN130;
- 使用 Add-VMNetworkAdapter 和 Set-VMNetworkAdapterVlan 创建相应的 Hyper-V 适配器;
- 使用上述工具使这些适配器可用于 WSL2;
- 在虚拟适配器(Hyper-V 虚拟以太网适配器)上,我必须禁用 Recv Segment Coalescing,否则“巨型帧”会被 pcap 捕获,并且将这些帧注入 linux tap 无法与标准 MTU 一起使用。