通过本地网络连接到 WSL2 服务器

Seb*_*vas 57 ruby-on-rails puma windows-subsystem-for-linux wsl-2

我正在我的 Windows 10 机器上使用 WSL2/Ubuntu 开发一个 rails 应用程序,这很棒!问题是我无法从同一网络中的另一台计算机连接到我的服务器

为了更清楚,我在 localhost:3000 上运行 Puma 服务器

我尝试了以下方法:

  1. 直接连接到分配给以太网适配器 vEthernet (WSL) 的 IP 地址 -> 172.26.208.1:3000
  2. 直接连接主机的IPv4地址-> 192.168.0.115
  3. 添加防火墙例外(使用 Bitdefender)
  4. 绑定上面的IP rails s -b 172.26.208.1 -p 3000

到目前为止,以上都没有奏效......我想做的是:

  • 在另一台笔记本电脑/平板电脑/手机上测试网站
  • 从另一台计算机使用 VScode

至少有什么我遗漏的吗?(以及对 VScode 部分的任何评论将不胜感激)

Akb*_*tov 57

看到这个视频,它帮助了我:

https://www.youtube.com/watch?v=yCK3esuYm4

netsh interface portproxy add v4tov4 listenport=<port-to-listen> listenaddress=0.0.0.0 connectport=<port-to-forward> connectaddress=<forward-to-this-IP-address>
Run Code Online (Sandbox Code Playgroud)

例如

netsh interface portproxy add v4tov4 listenport=3000 listenaddress=0.0.0.0 connectport=3000 connectaddress=172.30.16.3
Run Code Online (Sandbox Code Playgroud)

微软在他们的WSL1 到 WSL2 比较页面上发布了一些关于此的信息

不要忘记把反馈放在后面。

  • 谢谢,这很好用。对于不想观看整个视频的人,这需要在提升的 powershell 提示符下运行,而不是从 WSL 运行,“connectaddress”应该是您的 WSL IP,并且您可能需要通过 Windows 允许该端口防火墙。旁注,这与顶部答案中的脚本正在执行的操作相同,但很高兴只看到必要的命令而不是整个脚本。 (12认同)
  • 不要忘记将侦听端口添加到防火墙以便能够连接:`netsh advfirewallfirewalladdrulename=“OpenPort3000”dir=inaction=allowprotocol=TCPlocalport=3000` (9认同)
  • 不幸的是,对我不起作用。我正在尝试使用 iPhone 连接到本地网络服务器(以测试网站的移动版本)。我的代码在 WSL 机器中运行,并在“npm start”之后在端口“1337”上打开服务器。所以我输入了“netsh interface portproxy add v4tov4listenport=1337listenaddress=0.0.0.0connectport=1337connectaddress=127.22.240.165”。我虽然可以在我的 iPhone 上尝试:`192.168.1.32:1337`,但也许我误解了这个过程..有什么帮助吗? (4认同)
  • 我想补充一点,我遇到了一个奇怪的问题,运行“ipconfig”后,我在 powershell 中的 WSL 的 ipv4 与我的 Ubuntu 所说的不同。Ubuntu 所说的 IP 是正确的,但出于某种原因,“ipconfig”命令中的 WSL ipv4 不正确。可能与以太网端口有关。 (3认同)
  • @JakeAve 我觉得这些信息很关键。我也有这个。我的猜测是,Windows 将 WSL 的流量转发到“ipconfig”中列出的 IP,但 WSL 正在侦听 WSL 内“ip addr”列出的 IP。 (2认同)

Roe*_*lof 22

选项 1:使用端口转发

这个对我有用:

  1. 通过 xmeng1 的脚本运行端口转发:https ://gist.github.com/xmeng1/aae4b223e9ccc089911ee764928f5486

该脚本中的防火墙命令在我的系统上不起作用。所以我完全停用了 Windows 防火墙并使用以下剥离版本。(最终用户无论如何都会使用 3d 方防火墙,所以没关系)。

$remoteport = bash.exe -c "ifconfig eth0 | grep 'inet '"
$found = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';

if ($found)
{
  $remoteport = $matches[0];
} else {
  echo "The Script Exited, the ip address of WSL 2 cannot be found";
  exit;
}

#[Ports]

#All the ports you want to forward separated by coma
$ports=@(123,456);

#[Static ip]
#You can change the addr to your ip config to listen to a specific address
$addr='0.0.0.0';
$ports_a = $ports -join ",";

for ($i = 0; $i -lt $ports.length; $i++)
{
  $port = $ports[$i];
  iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr";
  iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=$addr connectport=$port connectaddress=$remoteport";
}

#Then so something, e.g.
#bash.exe -c "cd /g-inverter; ./start_docker.sh"
Run Code Online (Sandbox Code Playgroud)

您可能需要在脚本中为 ifconfig 设置“apt install net-tools”。在互联网上的某个地方还有一个不需要 ifconfig 的“ip addr”解决方案,在一个很好的线程中,我现在没有链接。

警告

这仅适用于 TCP 流量。netsh 接口 portproxy 不支持 UDP 流量的端口转发。

选项 2:桥接模式

解决方案:从 NAT 切换到桥接模式

WSL2 默认采用 NAT 模式。wsl2 系统在另一个子网中有另一个 ip,而不是主机。PC 来自外部对等点,只能通过 Windows IP 看到,而 wsl2 ip/net 是隐藏的/内部的。因此,所有流量都需要被 windows IP 接受,然后转发到 wsl2 ip(端口转发)。

还有另一种模式称为桥接模式。在桥接模式下,您的网络接口卡将与 wsl2 系统共享,并且它将在 wsl2 中获得自己的 IP/Net。因此,实际上您的网卡与两个系统(windows / wsl2)共享,并且将有两个 IP,就好像您有两个系统,每个系统都有自己的网卡。很酷的事情:当 Windows 也使用与 wsl2 应用程序(如 111)相同的端口时,您将永远不会发生端口冲突。

启用桥接模式

以管理员身份打开 Hyper-V 管理器

选择您的电脑,打开虚拟交换机管理器

选择 WSL

设置为外网

选择流量经过的网卡

然后登录wsl2终端并配置IP地址。例如

sudo ip addr add 192.168.0.116/24 dev eth0
Run Code Online (Sandbox Code Playgroud)

您需要使用另一个免费 IP(不是您的 Windows IP)。如果您的网络有 DHCP 服务器,您的 wsl 可以通过以下方式获得:

sudo ip addr flush dev eth0
sudo dhclient eth0
Run Code Online (Sandbox Code Playgroud)

警告

我还没有详细说明如何让 DNS 在这种情况下工作,以防您仍然希望能够访问互联网(apt 等)。有一些来自 MS 的文档写在 /etc/resolv.conf 中,也许执行那里写的内容并安装 resolvconf(在上述所有步骤之前,因为一旦开始桥接就没有互联网)可能会解决问题。

  • 更新:这种方法变得乏味,互联网上的线程变得越来越长,人们对此感到困扰。我们认为 WSL2 对于稳定的服务器托管来说还不够成熟,最终决定在 Windows 上安装所有服务器。WSL2 docker 实例将文件放入 Windows 文件夹,然后由 Windows 服务器托管。这意味着我们需要在每台 PC 上许可、安装和维护 3d 方产品。但我们对 WSL2 是否已做好行业准备还不够确信。我确信几年后情况会变得更好。我们现在 100% 长期稳定。 (3认同)
  • 选项 2 不可行,因为虚拟交换机管理器无法将 wsl 交换机更改为外部交换机。它将抛出错误 switch port delete failed ... (3认同)
  • 但要做好准备,因为一旦重新启动,它就会删除您的 Windows 网络适配器,您必须进入控制面板 -&gt; 网络和互联网 -&gt; 高级网络设置 -&gt; 网络重置。然后重新启动。那么,关键就在这里。wsl 也被炸了,所以你需要注销并重新安装。祝你好运。微软也彻底搞砸了。就像你怎么能不将 UDP 端口转发到 wsl 一样?xd 这是谁的鬼主意? (3认同)
  • 桥接模式听起来可能是一个很好的解决方案,但我运行 WSL2 的计算机没有启用 Hyper-V Windows 扩展,并且阅读 Hyper-V 文档让人担心此功能可能会导致问题。 (2认同)
  • “防火墙脚本对我不起作用,所以我完全关闭了防火墙”是个糟糕的建议。防火墙脚本确实对我有用,所以请保持防火墙完好无损! (2认同)

Cru*_*mmy 13

WSL2 在本地接口上公开端口(这就是为什么在 Windows 中,localhost:8080当您的8080服务在 WSL2 中运行时您可以访问),但它们会监听127.0.0.1(这就是为什么您无法yourhostname:8080在 LAN 的其他计算机上访问的原因)。

有一个工具可以解决这个问题,叫做 WSLHostPatcher,你可以在这里找到(通过发布部分下载):https : //github.com/CzBiX/WSLHostPatcher

WSLHostPatcher 将行为更改为侦听所有 IP,将任何 WSL2 服务暴露给网络上的所有计算机。

  1. https://github.com/CzBiX/WSLHostPatcher/releases下载最新版本(我测试了 v0.1.0)
  2. 解压文件
  3. 跑过 WSLHostPatcher.exe
  4. (重新)在 WSL2 中启动您的服务

现在应该可以通过网络上的其他计算机访问该服务。

  • WSLHostPatcher.exe 位于release.zip 文件中。如果您持怀疑态度,您可以在检查源代码后从存储库自行编译它。不是我的回购所以我不能保证! (2认同)
  • 在到处呆了几个小时之后,这对我来说就像一种魅力。非常感谢。 (2认同)

Dar*_*ryn 12

以下是我发现的对 WSL2(Windows 10 20H2 上的 Ubuntu 20)中运行的内容进行 LAN 开发访问的完整三个步骤:

\n

1. 启动时一次性:在 Windows 防火墙中打开入站 Expo 端口

\n

Windows 防火墙应该位于\xe2\x80\x94 上,不要将其关闭!\xe2\x80\x94,默认情况下它应该阻止入站尝试。

\n

以下命令将打开入站端口 19000\xe2\x80\x9319001,但仅在您配置为“专用”的网络上(这是部分,如果您在域中,则-Profile Private替换为):Domain

\n
    \n
  • 将 替换19000-19001为您需要的端口。
  • \n
  • 将其中的替换DisplayName为适合您的。这对于以后查找规则很方便。
  • \n
\n

(powershell 作为管理员)

\n
New-NetFireWallRule -Profile Private -DisplayName \'Expo ports for LAN development\' `\n    -Direction Inbound -LocalPort 19000-19001 -Action Allow -Protocol TCP\n
Run Code Online (Sandbox Code Playgroud)\n

Get-NetFirewallRule |Where-Object {$_.DisplayName -Match "Expo.*"}(您可以使用\xe2\x80\x94 将-Matcharg 替换为您选择的 DisplayName后进行检查)

\n

2.指向portproxyWSL;重新运行“每次 WSL 有新的 IP 地址时”

\n

(我还不确定 WSL IP 地址多久更改一次,但我怀疑只有重新启动才会更改)

\n

我在网上看到了一些东西,包括这里的其他答案,说 portproxyconnectaddress=127.0.0.1但它对我不起作用(WSL2,Windows 10 20H2)
\n我不能说为什么其他人发现它有效,我只能说反复测试对我来说没有127.0.0.1作用,但 WSL IP 地址确实有效。

\n

因此,这里有一个可重用的命令,用于自动将连接地址设置为正确的 WSL 地址:
\n (powershell \xe2\x80\x94 只是为了以管理员身份轻松内联Trim()\xe2\x80\x94)

\n
netsh interface portproxy add v4tov4 listenport=19000 listenaddress=0.0.0.0 `\n    connectport=19000 connectaddress=$($(wsl hostname -I).Trim());\n\nnetsh interface portproxy add v4tov4 listenport=19001 listenaddress=0.0.0.0 `\n    connectport=19001 connectaddress=$($(wsl hostname -I).Trim());\n
Run Code Online (Sandbox Code Playgroud)\n

3.(可选)如果您的 WSL 需要知道您的开发机器 LAN IP 地址

\n

(例如,Expo 等 QR 码移动应用程序)

\n

您需要在 WSL 中重新运行以下命令“每次开发主机都有一个新的 IP 地址”

\n
    \n
  • 这可能是变化最频繁的一个。当您更改网络(例如家庭/办公室)\xe2\x80\x94 时,您的笔记本电脑本地网络 IP 肯定会更改,并且在其他时间也可能会更改。
  • \n
\n

幸运的是,它也是可粘贴/可别名的:
\n WSL2 shell

\n
New-NetFireWallRule -Profile Private -DisplayName \'Expo ports for LAN development\' `\n    -Direction Inbound -LocalPort 19000-19001 -Action Allow -Protocol TCP\n
Run Code Online (Sandbox Code Playgroud)\n
\n

我“希望我不必重新运行一切,并且一切都可以自动化”,
\n但同样的懒惰让我很高兴至少让命令 2(和 3)易于“重新运行”并始终获得 LAN我需要访问 WSL2 托管的服务。

\n


小智 7

让 WSL2 发行版像网络上的任何其他客户端一样运行

建立在 Roelofs 建议 2 的基础上,这就是在我的情况下使一切顺利的原因。不幸的是,我太新鲜了,不能发表评论。

我的出发点: WSL2下的
Win 10 Pro
Ubuntu
(Docker with Linux容器)

我的目标:
从网络上的客户端获取 rtmp 流进出运行在 Ubuntu 机器上的 nginx 服务器。

建桥

就我而言,我无法让 Hyper-V 正确设置桥接。在Hyper-V 管理器的虚拟交换机部分为 WSL 交换机选择外部网络并点击应用后,它最终失败并出现错误 0x80070490。不知道为什么,也没有时间调查。WSL 没有运行,Docker 服务也没有运行。

相反,我只是将设置留在内部网络上,并在网络连接 (run->ncpa.cpl) 下以手动方式桥接接口。就我而言,WiFi 连接和vEthernet (WSL)。这样做之后,我立即失去了互联网连接,我花了很长时间才发现需要重新启动。(Windows 曾经没有要求我这样做!)

使 VM 成形

重新启动后,我现在可以从主机访问互联网,网桥设置为 DHCP 并继承了 WiFi 接口的 IP (192.168.1.246)。伟大的。

然而,VM 仍在获取虚拟交换机的 IP(或者无论您想查看它,Windows 似乎分配给交换机和 VM 的随机 172.xxx 地址)。

启动 Ubuntu,我决定做一个:

sudo ip addr flush dev eth0
Run Code Online (Sandbox Code Playgroud)

继续:

sudo dhclient eth0
Run Code Online (Sandbox Code Playgroud)

因为我使用的是 Windows 商店的 vanilla Ubuntu 发行版,没有systemd,没有乐趣,所以向我抛出了一些错误。尽管如此,它还是设法将网桥的 IP 添加到 eth0。由于这不是很方便,我摆脱了它:

sudo ip addr del 192.168.1.248/24 dev eth0
Run Code Online (Sandbox Code Playgroud)

但不是在偷看路由表之前:

user@vm:~$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.1.1     0.0.0.0         UG    0      0        0 eth0
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0
Run Code Online (Sandbox Code Playgroud)

删除旧 IP 后,我从 DHCP 范围之外添加了一个唯一的 IP:

sudo ip addr add 192.168.1.50/24 dev eth0
Run Code Online (Sandbox Code Playgroud)

我再次检查了路由表,第一个条目消失了。在这个阶段,我可以 ping LAN 但不能 ping WAN。

添加了条目:

sudo ip route add default via 192.168.1.1 dev eth0
Run Code Online (Sandbox Code Playgroud)

现在可以 Ping WAN IP,但无法解析 DNS。LMGTFM:添加永久 DNS 如果解决方案丢失,请归功于非静态

创建一个文件:/etc/wsl.conf。
将以下几行放入文件中

[网络]
generateResolvConf = false

在 cmd 窗口中,运行 wsl --shutdown
重启 WSL2
创建一个文件:/etc/resolv.conf。如果存在,用这个新文件替换现有的。
将以下几行放入文件中

名称服务器 8.8.8.8

或者您想使用的任何 DNS 服务器的 IP,重复步骤 3 和 4。

因此,总而言之,请检查您的路由并正确设置您的 DNS-conf。不幸的是,每次重新启动 WSL 时都会恢复 IP 设置。如果您不同意每次都手动执行此操作,请在此处此处讨论如何自动执行此操作。我没有时间找到我最喜欢的。

最好的问候亚历山大


小智 7

首先,您需要在您的机器上打开一个端口才能从您的网络访问它。

netsh advfirewall firewall add rule name="Allowing LAN connections" dir=in action=allow protocol=TCP localport=5000
Run Code Online (Sandbox Code Playgroud)

打开端口(在我的情况下为 5000)后,您需要将此端口转发到您的应用程序在 WSL 中侦听的端口。

netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=5000 connectaddress=localhost connectport=<the port that your app is listening on>
Run Code Online (Sandbox Code Playgroud)

注意:我将连接地址设置为localhost而不是 WSL 的 IP 地址,因为默认情况下,去往 localhost 的请求会转发到 WSL。通过这样做,您无需在每次重新启动机器时都设置端口转发,因为 WSL 的 IP 地址是动态的。

  • 我不知道为什么这不是最好的答案。它基本上是两个 PowerShell 粘贴,无需下载。 (11认同)
  • 嗯,localhost 对我不起作用 - 我必须直接指定 WSL IP 地址。 (5认同)
  • 将“connectaddress”设置为“localhost”对我来说很有效。我尝试按照[针对此确切问题的微软文档](https://learn.microsoft.com/en-us/windows/wsl/networking#accessing-a-wsl-2-distribution-from-your-local-area -网络-LAN)。他们说将“connectaddress”设置为 WSL2 虚拟机的 IP,这对我不起作用。 (3认同)
  • 只有 localhost 或 127.0.0.1 对我有用。指定 WSL ip 在我的情况下不起作用。 (2认同)
  • 在 win11 上为我工作,wsl2 全部更新并使用 localhost 作为连接地址 (2认同)

ant*_*alm 7

这对我使用 wsl2 有用。我在 wsl2 中有一个应用程序正在监听 port 4200。在管理员提升的 powershell中:

添加代理

netsh interface portproxy add v4tov4 listenport=8080 connectport=4200 connectaddress=127.0.0.1

请注意缺少listenaddress=参数和不同的侦听端口8080而不是4200

添加防火墙规则

netsh advfirewall firewall add rule name= "Open Port 8080" dir=in action=allow protocol=TCP localport=8080

然后在我连接wifi的手机上访问http://192.168.1.2:8080

打扫干净

您可以使用以下命令删除您的代理并netsh interface portproxy delete v4tov4 listenport=8080使用以下命令删除您的防火墙规则netsh advfirewall firewall delete rule name="Open port 8080"

笔记

显然,请更改您的机箱的端口以及192.168.1.2LAN 上的 PC IP。使用ipconfig来找到它。您可能需要确保在 wsl2 中运行的代码绑定在0.0.0.0.

祝你好运。


小智 6

考虑到上述(正确)解决方案,这是一个对我有用的简化的单行版本:

  1. 使用“ifconfig”查找您的 wsl2 公共 IP 地址。请记住,每次 Windows 重新启动时,Hyper-V 交换机 IP 都会更改,因此 wsl2 中的公共 IP 也会更改。 在此处输入图片说明
  1. 使用在上一步中在 connectaddress 参数中找到的 IP 运行以下命令:

    netsh interface portproxy add v4tov4 listenport= listenaddress=0.0.0.0 connectport= connectaddress=172.24.26.277
    Run Code Online (Sandbox Code Playgroud)

参数说明:

  • listenport : Windows 将侦听的端口

  • listenaddress:您的 Windows 将侦听的地址。通常 0.0.0.0 应该可以。

  • connectport:您的 Linux 发行版通过 wsl2 将侦听的端口。

  • connectaddress:您的Linux实例WSL2的公网IP(步骤找到1)

以管理员身份使用 cmd 或 PowerShell 运行上述命令。

  • 而且您不需要执行“ifconfig”。`hostname --all-ip-addresses` 可以完成这项工作。 (2认同)

Mal*_*alt 6

另一种解决方案是将 WSL2 直接桥接到相关网络适配器。我尝试在 Hyper-V 中执行此操作,但无法使其工作。然而,有效的方法是Control Panel\Network and Internet\Network Connections选择 NIC(Ethernet 3在我的例子中)并vEthernet (WSL)通过右键单击并选择“桥接连接”来桥接它们:

桥接连接菜单项

你最终应该得到这样的结果:

桥接连接

桥接设置完成后,让 Windows 执行一分钟左右(认真的!),然后再继续。

接下来打开 WSL 并让它运行 dhcp 来获取新地址:

sudo ip addr flush dev eth0 && sudo dhclient eth0
Run Code Online (Sandbox Code Playgroud)

此时,WSL 和 Windows 都应该具有连接。通过 ping 一些 IP 地址(如 1.1.1.1 或 8.8.8.8)进行检查。如果这不起作用,请拆除桥梁并重试。请记住在 Windows 配置所有内容时等待一两分钟。

此外,请确保它eth0具有来自 LAN ( ) 的地址ip addr sh eth0

现在的问题是 WSL 可能无法解析域名,因为 WSL/etc/resolv.conf在启动时创建指向不再存在的虚拟网关。这可以通过要求 wsl 不要创建来解决,方法是/etc/resolv.conf将以下内容附加到/etc/wsl.conf(如果文件不存在则创建文件):

[network]
generateResolvConf=false
Run Code Online (Sandbox Code Playgroud)

然后通过重新启动LxssManagerWindows 服务来重新启动 wsl。唯一剩下的就是在 WSL 中设置替代 DNS 服务器。不用生成/etc/resolv.conf,只需创建一个/etc/resolv.conf类似以下内容的 :

nameserver 1.1.1.1
nameserver 1.0.0.1
Run Code Online (Sandbox Code Playgroud)

就是这样!WSL 现在应该桥接到您的网络,并在其上有自己的唯一地址。


小智 5

  1. 在 WSL 上安装 ssh 服务器

  2. 在 windows 上找一些 ssh 客户端

  3. 在 windows 上执行:(Windows 的 IP 为 192.168.xx,WSL ip 为 172.28.xx)

    ssh -L 192.168.x.x:3000:172.28.x.x:3000 someuser@172.28.x.x

如果它不起作用,请尝试使用另一个本地端口,例如 (192.168.xx: 3001 :172.28.xx:3000)


kwe*_*rle -11

尝试-b 0.0.0.0 一下 这在其他操作系统上也适用