我正在Windows 10机器上使用WSL2 / Ubuntu开发Rails应用程序,太好了! 问题是我无法从同一网络中的另一台计算机连接到服务器。
为进一步清楚起见,我在localhost:3000上运行Puma服务器
我尝试了以下操作:
myMap.insert({pts.at<Point>(5), true});
以上的IP 到目前为止,以上方法均无效...我想做的是:
我是否缺少至少可以正确看到该网站的内容? (以及对VScode部分的任何评论都将受到赞赏)
答案 0 :(得分:12)
观看此视频,对我有帮助:
https://www.youtube.com/watch?v=yCK3easuYm4
netsh interface portproxy add v4tov4 listenport=<port-to-listen> listenaddress=0.0.0.0 connectport=<port-to-forward> connectaddress=<forward-to-this-IP-address>
例如
netsh interface portproxy add v4tov4 listenport=3000 listenaddress=0.0.0.0 connectport=3000 connectaddress=172.30.16.3
不要忘记在此之后发表反馈。
答案 1 :(得分:10)
这个为我工作:
该脚本中的防火墙命令在我的系统上不起作用。因此,我完全停用了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"
您可能需要在脚本中为ifconfig“ apt install net-tools”。互联网上还有一个解决方案,其中“ ip addr”不需要大线程中的“ ifconfig”,我现在没有链接。
注意事项
这仅适用于TCP通信。 netsh接口portproxy不支持UDP通信的端口警告。
解决方案:从NAT切换到网桥模式
WSL2默认为NAT模式。那里的wsl2系统在除主机之外的另一个子网中具有另一个IP。 PC来自外部对等方,只有Windows IP才可见,而wsl2 ip / net是隐藏/内部的。因此,所有流量都需要Windows IP接受,然后转发到wsl2 ip(端口转发)。
还有另一种模式称为桥接模式。在桥接模式下,您的网络接口卡将共享到wsl2系统,并且它将在wsl2中获得自己的IP /网络。因此,实际上,您的网卡被两个系统共享(windows / wsl2),并且将具有两个IP,就好像您有两个具有各自网卡的系统一样。很酷的事情:当Windows使用与wsl2应用程序(例如111)相同的端口时,您将永远不会发生端口冲突。
启用桥接模式
以管理员身份打开Hyper-V Manager
选择您的电脑,打开虚拟交换机管理器
选择WSL
设置为外部网络
选择流量通过的网卡
然后登录到wsl2终端并配置IP地址。例如
sudo ip addr add 192.168.0.116/24 dev eth0
您需要使用另一个免费IP(不是Windows IP)。如果您的网络中有DHCP服务器,则您的wsl可以通过以下方法之一获得:
sudo ip addr flush dev eth0
sudo dhclient eth0
注意事项
我还没有详细说明如何在这种情况下使DNS工作,以防万一您仍然希望能够访问Internet(apt等)。有一些来自MS的文档在/etc/resolv.conf中编写,也许可以执行那里写的内容并安装resolvconf(在上述所有步骤之前,因为一旦开始桥接就没有互联网,即可)。
答案 2 :(得分:9)
WSL2 在本地接口上公开端口(这就是为什么在 Windows 中,当您的 localhost:8080
服务在 WSL2 中运行时您可以访问 8080
),但它们监听 127.0.0.1
(这是为什么您无法在局域网的其他计算机上访问 yourhostname:8080
)。
有一个名为 WSLHostPatcher 的工具可以解决此问题,您可以在此处找到该工具(通过“发布”部分下载):https://github.com/CzBiX/WSLHostPatcher
WSLHostPatcher 将行为更改为侦听所有 IP,将任何 WSL2 服务暴露给您网络上的所有计算机。
WSLHostPatcher.exe
现在应该可以通过网络上的其他计算机访问该服务。
答案 3 :(得分:4)
首先,您需要在您的机器上打开一个端口,以便能够从您的网络访问它。
netsh advfirewall firewall add rule name="Allowing LAN connections" dir=in action=allow protocol=TCP localport=5000
打开端口(在我的情况下为 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>
注意:我将 connectaddress 设置为 localhost 而不是 WSL 的 IP 地址,因为默认情况下发送到 localhost 的请求是转发给 WSL。通过这样做,您无需在每次重新启动机器时都设置端口转发,因为 WSL 的 IP 地址是动态的。
答案 4 :(得分:3)
在Roelofs建议2的基础上,这是使我的情况不停变化的原因。我太新鲜了,只可惜发表评论。
我的出发点:
Win 10专业版
WSL2下的Ubuntu
(带有Linux容器的Docker)
我的目标:
从网络上的客户端获取rtmp流,使其往返于Ubuntu计算机上运行的nginx服务器。
就我而言,我无法让Hyper-V正确设置网桥。在Hyper-V管理器的“虚拟交换机”部分中为WSL交换机选择<外部>外部网络并单击“应用”后,它最终失败,错误为0x80070490。不知道为什么,没有时间去调查。 WSL没有运行,Docker服务也没有运行。
相反,我只是将设置保留在内部网络上,并以手动方式在网络连接(run-> ncpa.cpl)下桥接了接口。就我而言,是WiFi连接和 vEthernet(WSL)。 完成此操作后,我立即失去了互联网连接,这使我花了很长时间尴尬地发现需要重新启动。 (Windows一次没有要求我这样做!)
重新启动后,我现在可以从主机访问Internet,网桥设置为DHCP,并且继承了WiFi接口的IP(192.168.1.246)。很好。
但是,VM仍在获取虚拟交换机的IP(或者您想查看它,Windows似乎为该交换机以及VM分配的随机172.x.x.x地址)。
启动Ubuntu,我决定执行以下操作:
sudo ip addr flush dev eth0
继续:
sudo dhclient eth0
自从我使用Windows商店的香草Ubuntu发行版以来,我就犯了一些错误,没有 systemd ,也没有乐趣。尽管如此,它确实设法将网桥的IP添加到eth0。因为这不是很方便,所以我用以下方法摆脱了这个问题:
sudo ip addr del 192.168.1.248/24 dev eth0
但不要先窥视路由表:
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
删除旧IP后,我在DHCP范围之外添加了一个唯一IP:
sudo ip addr add 192.168.1.50/24 dev eth0
我再次检查了路由表,第一个条目不见了。在此阶段,我可以ping LAN,但不能ping广域网。
将条目添加回:
sudo ip route add default via 192.168.1.1 dev eth0
现在可以Ping WAN IP,但没有DNS解析。 LMGTFM:Adding permanent DNS 万一解决方案丢失了,这里就是归功于非静态:
Create a file: /etc/wsl.conf. Put the following lines in the file [network] generateResolvConf = false In a cmd window, run wsl --shutdown Restart WSL2 Create a file: /etc/resolv.conf. If it exists, replace existing one with this new file. Put the following lines in the file nameserver 8.8.8.8 Or the IP of whatever DNS server you want to use, repeat step 3 and 4.
因此,最后,请检查路由并正确设置DNS-conf。不幸的是,每次重启WSL时IP设置都会恢复。如果您不确定每次手动执行此操作,都将讨论如何here和here使其自动化。我没有时间找到我的最爱。
最好的问候 亚历山大
答案 5 :(得分:1)
这里提供的解决方案可能比提供的其他解决方案更简单。除了正在使用的WSL2实例之外,还需要安装socat
的WSL1实例。
在WSL1实例上,像这样启动socat
:
socat -d TCP-LISTEN:3000,reuseaddr,fork TCP:localhost:3000
像这样启动socat时,Windows会询问您是否要允许网络访问该端口。确认。
确保您的puma绑定到所有接口上的端口3000。
您现在可以从LAN访问您的开发服务器。这里发生的是,socat正在将请求从您的以太网端口上的3000转发到本地主机上的端口3000,这将被Windows神奇地转发到WSL2。
(我目前正在使用此精确设置从LAN上的iOS应用访问WSL2上的Django开发服务器。)
答案 6 :(得分:0)
不幸的是,对我来说,这是一种简化的情况,因为我的家庭网络是由路由器定义的。由于我的家庭设备无法使用背对背连接进行通信,并且我的网络受到路由器防火墙的保护,因此我必须遵守路由器的配置。
答案 7 :(得分:0)
在WSL上安装ssh服务器
在Windows上找到一些ssh客户端
在Windows上执行:(Windows的IP为192.168.x.x,WSL ip为172.28.x.x)
ssh -L 192.168.x.x:3000:172.28.x.x:3000 someuser@172.28.x.x
如果它不起作用,请尝试使用其他本地端口,例如(192.168.x.x: 3001 :172.28.x.x:3000)
答案 8 :(得分:0)
关于桥接模式-Windows将阻止在运行任何Linux发行版时修改WSL虚拟交换机(访问被拒绝错误)。另一方面,启动第一个Linux发行版时将创建WSL开关。 我做了如下:
答案 9 :(得分:0)
考虑到上述(正确)解决方案,这是一个简化的衬板版本,对我有用:
使用上一步在connectaddress参数中找到的IP运行以下命令:
netsh interface portproxy add v4tov4 listenport= listenaddress=0.0.0.0 connectport= connectaddress=172.24.26.277
参数说明:
listenport :Windows将监听的端口
listenaddress :Windows将监听的地址。通常应该使用0.0.0.0。
connectport :Linux发行版通过wsl2将使用的端口 听。
connectaddress :Linux wsl2实例的公共IP (在步骤1中找到)
使用cmd或PowerShell作为管理员来运行上述命令。
答案 10 :(得分:0)
这是我发现要进行局域网开发以访问在WSL2(Windows 10 20H2上的Ubuntu 20)上运行的程序的全部步骤:
Windows防火墙应处于打开状态-请勿将其关闭!-并且默认情况下它应阻止入站尝试。
以下内容将打开端口19000–19006(入站), ,但仅在您配置为“专用”的网络上 (即-Profile Private
部分):
将19000-19006
替换为您需要的端口。
(以powershell作为管理员)
New-NetFireWallRule -Profile Private -DisplayName 'Expo ports for LAN development' `
-Direction Inbound -LocalPort 19000-19006 -Action Allow -Protocol TCP
(您可以在以后使用Get-NetFirewallRule |Where-Object {$_.DisplayName -Match "Expo.*"}
进行检查)
portproxy
指向WSL;重新运行“每次WSL有一个新IP地址” (我不确定WSL IP地址多久更改一次,但我怀疑只有重启才能实现)
我在网上看到了东西,包括此处的其他答案,对connectaddress=127.0.0.1
说了portproxy,但对我来说(没有)有用(WSL2,Windows 10 20H2)。
我不能说为什么其他人发现它起作用,我只能说重复测试对我来说证明127.0.0.1
不起作用,但是WSL IP地址起作用了。
因此,这是一个可重用的命令,用于将connectaddress自动设置为正确的WSL地址:
(powershell —仅用于简单的内联Trim()
—以管理员身份)
netsh interface portproxy add v4tov4 listenport=19000 listenaddress=0.0.0.0 `
connectport=19000 connectaddress=$($(wsl hostname -I).Trim());
netsh interface portproxy add v4tov4 listenport=19001 listenaddress=0.0.0.0 `
connectport=19001 connectaddress=$($(wsl hostname -I).Trim());
(例如,世博会的QR码移动应用)
您需要在WSL中重新运行以下命令“每次开发主机都有一个新IP地址”
幸运的是,它也是可粘贴/可别名的:
WSL2 shell
netsh.exe interface ip show address "Wi-Fi" | grep 'IP Address' | sed -r 's/^.*IP Address:\W*//'
# e.g. for Expo, I used:
export REACT_NATIVE_PACKAGER_HOSTNAME=$(netsh.exe interface ip show address "Wi-Fi" | grep 'IP Address' | sed -r 's/^.*IP Address:\W*//')
echo Meteor will use dev machine IP address: $REACT_NATIVE_PACKAGER_HOSTNAME
我“希望我不必重新运行,并且可以全部自动化”,
但是同样的懒惰使我很高兴至少可以轻松地“重新运行”命令2(和3)并始终获得对WSL2托管服务所需的LAN访问权限。
答案 11 :(得分:0)
最后我得到了一个解决方案,它必须在 Windows 主机启动后只运行一次,同时处理多个 WSL2 实例,并且在 WSL2 实例重新启动时不必重新运行!
>缺点:不能监听0.0.0.0;您必须明确指定用于侦听的 IP 或适配器。 (此版本仅侦听一个 IP 地址,但可以轻松扩展为使用列表)。
$ports = @(8000,8001); # ports to forward
$iface = "Ethernet"; # alias of the Adapter to listen on
# if your host has a fixed IP, you can specify it here explicitly
# and remove the ping-and-if safeguard;
# but 0.0.0.0 won't work!
$external_ip = (Get-NetIPAddress -AddressFamily IPv4 -InterfaceAlias $iface).IPv4Address;
ping -n 1 "$external_ip" > $null
if( !$? ) {
echo "error: cannot determine the external IP address";
exit 1;
}
$firewall_rule_name = "WSL2 Firewall Hole"
Remove-NetFireWallRule -DisplayName "$firewall_rule_name"
New-NetFireWallRule -DisplayName "$firewall_rule_name" -Direction Outbound -LocalPort $ports -Action Allow -Protocol TCP
New-NetFireWallRule -DisplayName "$firewall_rule_name" -Direction Inbound -LocalPort $ports -Action Allow -Protocol TCP
ForEach( $port in $ports ) {
netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$external_ip
netsh interface portproxy add v4tov4 listenport=$port listenaddress=$external_ip connectport=$port connectaddress=127.0.0.1
}
学分:
localhost
而不是获取正在运行的 WSL2 实例的 IP 地址的想法是由 Charl Botha 在这里从 this answer 收集的。原始 edwindijas 的脚本对我不起作用,因为我在受限用户下运行 WSL2,脚本必须以管理员身份运行,并且以管理员身份运行 bash
或 wsl -e
会获得一个新的 WSL2 实例使用不同的 IP 地址。
答案 12 :(得分:-4)
尝试-b 0.0.0.0
那就是在其他操作系统上能用的