wsl网络情况较复杂,本篇除了官方的网络配置事项,主要添加了:
1.wsl自动获取宿主机ip的脚本。
2.wsl设置固定(静态)ip的配置方法。

导航

一 基于官方说明

建议先阅读官方文档:https://learn.microsoft.com/zh-cn/windows/wsl/networking

通过官方配置和以下教程,可以达到如下效果,无需记住任何ip

  • windows访问wsl:使用localhost即可(但是不能使用127.0.0.1)
  • wsl访问windows:使用自动配置的my.win即可(见下)

如果系统是专业版(可开启Hyper-V),可参考 https://github.com/luxzg/WSL2-fixes 配置wsl桥接网络。
本文相关配置在使用wsl桥接网络的情况下可能无效或没必要,不过桥接网络本身还没有被wsl正式支持的。
且我用的是家庭版,虽然也可以开启,但可能有风险,故暂不使用。

1 wsl自动获取宿主机ip

注意:如果采用了下面设置静态ip的方法,会一并设置windows静态ip,就不需要使用这里的脚本了!

见:https://learn.microsoft.com/zh-cn/windows/wsl/networking#accessing-windows-networking-apps-from-linux-host-ip

这里的脚本主要是负责自动获取win-ip、添加host映射:
1.wsl的hosts文件默认情况下是从windows继承过来的,每次都会重新生成(可通过wsl.conf控制),所以需先删除原来的my.win配置
2.sed结果需要使用/tmp/hosts作为中转,不能直接输出到/etc/hosts,否则/etc/hosts会被清空

cat << 'EOF' >> /etc/profile
host_ip=$(cat /etc/resolv.conf |grep "nameserver" |cut -f 2 -d " ")
sed -e "/my.win/d"  /etc/hosts  > /tmp/hosts
cat /tmp/hosts > /etc/hosts
echo "$host_ip my.win" >>/etc/hosts
EOF

另外在windows的hosts文件中配置 127.0.0.1 my.win,
这样,在windows上启动的服务,不管在wsl还是windows上,都可以通过my.win访问到了

2 局域网访问wsl2的操作示例

见:https://learn.microsoft.com/zh-cn/windows/wsl/networking#accessing-a-wsl-2-distribution-from-your-local-area-network-lan

需要使用netsh interface portproxy功能,按照help提示操作就行

以下为示例,局域网其他机器只需要连接宿主机的19909端口即可访问wsl2内19909端口的内容:

在powershell管理员模式下执行命令,

# 重置端口代理
netsh interface portproxy reset
# 最好一并设置v4tov6,例如springboot网络默认是v6的
netsh interface portproxy add v4tov6 listenport=19909 listenaddress=0.0.0.0 connectport=19909 connectaddress=localhost
netsh interface portproxy add v4tov4 listenport=19909 listenaddress=0.0.0.0 connectport=19909 connectaddress=localhost
# 查看端口配置
netsh interface portproxy show all

二 wsl配置固定ip

除了docker访问wsl,其他大部分场景下不需要这个功能

windows的docker不支持使用host网络,也就是不能通过localhost访问wsl
ip是可以的,但wsl的ip每次启动都会变,所以比较麻烦,这里通过使用固定ip解决

参考:https://www.cnblogs.com/Likfees/p/16750300.html

注意此处调用了wudo(见WSL开发系列-基础篇)以使用管理员权限调用netsh工具

cat << 'EOF' > setup-static-ip.sh 
#!/bin/bash

WSL_IP=192.168.95.100
WIN_IP=192.168.95.101
WSL_BROADCAST=192.168.95.255
WIN_IP_SET_RESULT=$(/mnt/c/WINDOWS/system32/netsh.exe interface ip show addresses "vEthernet (WSL)" | grep -sc "$WIN_IP" )
if [ $WIN_IP_SET_RESULT == 0 ]; then
  wudo /mnt/c/WINDOWS/system32/netsh.exe interface ip add address "vEthernet (WSL)" address=$WIN_IP/24
  echo "set WIN_IP $WIN_IP success "
fi

WSL_IP_SET_RESULT=$(ip addr show eth0 | grep -sc "$WSL_IP/24" )
if [ $WSL_IP_SET_RESULT == 0 ]; then
  ip addr add $WSL_IP/24 broadcast $WSL_BROADCAST dev eth0 label eth0:staticip
  echo "set WSL_IP $WSL_IP success "
fi
echo "check and set WSL_IP($WSL_IP) WIN_IP($WIN_IP) success "
EOF

# 设置权限
chmod a+x setup-static-ip.sh
# 测试执行
source setup-static-ip.sh
# 验证结果:wsl
ip addr show eth0
# 验证结果:win
/mnt/c/WINDOWS/system32/netsh.exe interface ip show addresses "vEthernet (WSL)"
# 拷贝到系统路径下
mv setup-static-ip.sh /usr/bin/
# 再次测试
setup-static-ip.sh
echo "setup-static-ip.sh" >> /etc/profile

现在直接在windows配置hosts就行了(wsl默认情况下会复制windows的hosts)

192.168.95.101 my.win
192.168.95.100 my.wsl

Q.E.D.