那个脚本中的防火墙命令在我的系统上不起作用。因此,我完全关闭了 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 接口端口代理不支持端口转发的 UDP 流量。
选项2: 桥接模式
解决方案: 从 NAT 切换到桥接模式
WSL2 comes by default in NAT mode. There the wsl2 system has another ip in another subnet than the host. The PC is from external peers only visible by the windows IP and the wsl2 ip/net is hidden/internal. So all traffic would need to be accepted by the windows IP and then forwarded to the wsl2 ip (port forwarding).
还有另一种模式叫做桥接模式。在桥接模式下,您的网络接口卡将共享给 wsl2系统,它将在 wsl2中获得自己的 IP/Net。因此,实际上您的网卡被两个系统(windows/wsl2)共享,并且将有两个 IP,就好像您有两个系统,每个系统都有自己的网卡一样。很酷的事情: 当 Windows 和你的 wsl2应用程序(比如111)使用相同的端口时,你永远不会有端口冲突。
启动连接模式
作为管理员打开 Hyper-V Manager
选择你的电脑,打开虚拟交换机管理器
选择 WSL
Set to external network
选择流量通过的网卡
然后登录到 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 在这种情况下工作的情况下,你想仍然能够访问互联网(适合等)。有一些来自 MS 的文档写在/etc/Resolv.conf 中,也许执行写在那里的内容并安装 Resolvconf (在上述所有步骤之前,因为一旦开始连接就没有互联网)可能会起到作用。
重新启动后,我现在可以从主机上访问互联网,网桥被设置为 DHCP,并继承了 WiFi 接口的 IP (192.168.1.246)。很好。
然而,虚拟机仍然获得虚拟交换机的 IP 地址(或者不管你想怎么查看它,Windows 似乎分配给交换机和虚拟机的随机172.x.x.x 地址)。
启动 Ubuntu,我决定做一个:
sudo ip addr flush dev eth0
继续:
sudo dhclient eth0
自从我使用 Windows 商店的普通 Ubuntu 发行版,没有 系统,没有乐趣,我就犯了一些错误。尽管如此,它还是设法将桥的 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,但不是 WAN。
在条目后面添加了:
sudo ip route add default via 192.168.1.1 dev eth0
现在可以对广域网 IP 进行定位,但是没有 DNS 解析。
添加永久 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 设置。如果你不同意这样做手动每次有关于如何自动化它 给你和 给你的讨论。我还没来得及找到我最喜欢的。
这可能是变化最频繁的一个。当你改变网络(如家庭/办公室)时,你的笔记本本地网络 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
I "wish I didn't have to re-run things and it could all be automated",
但是同样的懒惰使我很高兴至少有命令2(和命令3)可以“重新运行”,并且始终能够访问我的 WSL2托管服务所需的局域网。
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=5000 connectaddress=localhost connectport=<the port that your app is listening on>
注意: 我将 连接地址设置为 localhost而不是 WSL 的 IP 地址,因为默认情况下,发送到 localhost 的请求会被转发到 WSL。通过这样做,您不必在每次重新启动计算机时都设置端口转发,因为 WSL 的 IP 地址是动态的。
另一种解决方案是将 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
At this point, both WSL and Windows should have connectivity. Check by pinging some IP address like 1.1.1.1 or 8.8.8.8. If that doesn't work, dismantle the bridge and try again. Remember to wait for a minute or two while Windows configures everything.
所以,在过去的两天里,我在这个问题上挣扎了一段时间,似乎没有任何东西起作用,无论是在这条线上还是在别的地方。我最终通过拼凑我所看到的一些东西得到了解决,我想我应该把我的解决方案贴在这里,以防它对任何人都有帮助。不过有几点需要注意。首先,我肯定不是 Linux 专家,所以“它能工作”只是我真正唯一的考虑:)其次,这是在一个家用开发服务器上,这意味着安全不是我最大的问题(服务器不会以任何方式暴露在我的局域网之外) ,所以我做了一些事情,我不会在一个真正的,重要的机器上做。最后,我不需要它一直工作,这意味着我可以在服务器重启后自己做一些事情来让它全部工作。
考虑到所有这些,第一步是,正如上面麦芽所描述的,将 WSL 适配器与服务器的物理适配器连接起来。在我的例子中,服务器有一个静态 IP,所以我配置了 NetworkBridge 适配器,它为 IPv4提供了一个静态 IP、网关和 DNS 服务器。
之后,我在主目录中编写了以下名为 Start _ asks. sh的脚本:
#!/bin/bash
clear
echo Running startup tasks...
# Clear existing IP config
sudo ip addr flush eth0
echo .
sleep 2
# Add static IP
sudo ip addr add 192.168.1.100/24 dev eth0
echo .
sleep 2
# Remove existing default gateway
sudo ip route del default
echo .
sleep 2
# Add default gateway
sudo ip route add default via 192.168.1.1
echo .
sleep 2
# Remove existing name resolution config file
sudo rm /etc/resolv.conf
echo .
sleep 2
# Create name resolution config file
sudo touch /etc/resolv.conf
echo .
sleep 2
# Update permissions on file so we can edit it
sudo chmod 777 /etc/resolv.conf
echo .
sleep 2
# Add name servers
sudo echo "nameserver 8.8.8.8" >> /etc/resolv.conf
echo .
sleep 2
sudo echo "nameserver 1.1.1.1" >> /etc/resolv.conf
echo .
sleep 2
echo - Static IP set
echo .
echo ...done!
@ECHO OFF
REM ** Set WSL Distro, Distro Port, Host Port
SET LXDISTRO=WinKDE
SET WSL2PORT=3389
SET HOSTPORT=13389
REM ** Reset any existing port proxies and delete any stale firewall rule
NETSH INTERFACE PORTPROXY RESET & NETSH AdvFirewall Firewall delete rule name="%LXDISTRO% Port Forward" > NUL
REM ** Get IP from WSL2 instance and write it out to IP.tmp
WSL -d %LXDISTRO% -- ip addr show eth0 ^| grep -oP '(?^<=inet\s)\d+(\.\d+){3}' > IP.TMP
REM ** Read IP.tmp back into batch variable
SET /p IP=<IP.TMP
REM ** Create the port proxy
NETSH INTERFACE PORTPROXY ADD v4tov4 listenport=%HOSTPORT% listenaddress=0.0.0.0 connectport=%WSL2PORT% connectaddress=%IP%
REM ** Create a new firewall rule for the port listening on the LAN
NETSH AdvFirewall Firewall add rule name="%LXDISTRO% Port Forward" dir=in action=allow protocol=TCP localport=%HOSTPORT% > NUL
REM ** Summary
ECHO WSL2 Virtual Machine %IP%:%WSL2PORT%now accepting traffic on %COMPUTERNAME%:%HOSTPORT%
Output::
WSL2 Virtual Machine 172.17.109.95:3389 now accepting traffic on MYCOMPUTER:13389