如何让 Windows 程序监听来自 WSL 的连接而不绑定到 0.0.0.0?

How can I have a Windows program listening for connections coming from WSL without binding to 0.0.0.0?

本机服务需要可以从 WSL(或其他 Windows 进程)中的东西 运行 访问,但不能从外部世界访问。

我看到 WSL 设置了一个虚拟接口,但不清楚它是否有固定 IP 或者我应该怎么做才能发现它,因为我需要它以标准方式合理地工作,而不管机器上一切都已安装。

可能会有点问题,具体取决于具体的用例。您 运行 的情况与我前一段时间 this answer 的情况正好相反。这些选项与该用例相似但不完全相同:

选项 1:WSL1

我能想到的最简单的方法是简单地使用 WSL1,假设您不需要 WSL2 的任何功能。 WSL1 在实际的 Windows NIC 上运行,因此如果您将 Windows 服务绑定到 127.0.0.1(并且,如果需要,::1),那么 WSL1 中的任何 运行将能够看到它,并且 Windows 服务将接受来自 WSL1 进程的连接,就好像它们来自 Windows localhost.


选项 2:WSL2 Windows 服务绑定到两个地址

对于 WSL2,您需要 Windows 服务来监听 127.0.0.1,当然,Windows 进程,以及 [= 提供的 vNIC 地址45=]:

> ipconfig.exe /all
...
Ethernet adapter vEthernet (WSL):

   Connection-specific DNS Suffix  . :
   Description . . . . . . . . . . . : Hyper-V Virtual Ethernet Adapter
   ...
   IPv4 Address. . . . . . . . . . . : 172.18.48.1(Preferred)
   Subnet Mask . . . . . . . . . . . : 255.255.240.0
   ...

不幸的是,该地址在重新启动时会发生变化,因此您需要一些方法来检索它并通过配置或启动将其传递给 Windows 服务。它可以通过以下方式从 WSL 中获取:

ip route | head -1 | cut -d" " -f3

但这可能会违反您的“需要它以相同方式运行”的规则。

当然,这也假定您可以将服务绑定到两个不同的地址。


可能的选项 3:WSL2 和 WSL1 之间的 socat

如果您查看我的 Super User answer,您将看到一种将 WSL2 实例与 WSL1 实例连接的方法。这里的流程是相反的,因为在您的情况下,需要建立连接 WSL2 实例 Windows 主机。不幸的是,如果你想走那条路,我必须暂时把 socat 命令行的修改留给你。

最后最好在0.0.0.0上绑定添加依赖防火墙限制访问服务

这不太安全,也不太理想,但这是截至 2021 年 10 月唯一实用的选择。

默认情况下拒绝外部连接。以下规则允许它们来自 WSL 接口。

New-NetFirewallRule -DisplayName "WSL" -Direction Inbound -InterfaceAlias "vEthernet (WSL)" -Action Allow

要连接到这个 IP,仍然需要通过检查活动名称服务器配置从 WSL 机器内部发现它。

Microsoft 的设计选择非常糟糕,大多数虚拟机都可以轻松做到这一点。