Windows 简单访问 WSL2

想必很多人在使用 WSL 时都遇到过与 Windows 主机通信的问题。在日常编程中，很常用的场景是在 Windows 中访问部署在 WSL 中的数据库、web 或其它服务等。Windows 本身是会做映射的，比如使用如下命令启动一个 http server：

Copy
➜ source git:(master) python -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

这时在 Windows 上访问 localhost:8000是可以正常打开的。但在某些其它场景（如数据库连接时），该映射又会失效。可能是因为 WSL 默认只映射了 http 服务的端口？（存疑）

为了解决上述问题，我们需要一种手段来确保 Windows 主机能够轻松访问到 WSL。以下列举三种解决方式，并最后详细描述我的解决方案。

手动查找 WSL 的局域网 IP，并使用该 IP 访问

这种方法最为简单直白，手动找到 WSL 的 IP 访问即可。

在 WSL 中执行ifconfig命令，可获得大量输出：

Copy
➜ source git:(master) ifconfig
.....
eth0: .......
inet 172.21.255.188 .....
.....

找到上面inet后的 IP 地址，即为 WSL 的局域网 IP。

但 WSL 的 IP 在每次启动时都会变化，如果经常需要访问 WSL 的话该方法并不是一个好选择。

连接映射

使用 HobaiRiku/wsl2-auto-portproxy 将 WSL 中的所有 TCP 端口映射到 Windows localhost 上（暂不支持 UDP）。

该方法在需要访问 WSL 时下载二进制文件运行即可，不需要额外操作。

将 WSL IP 添加到 Windows 的 hosts 文件中

刚刚第一种方法的缺点是 IP 在每次启动时都会变化，这让我们想到了域名。

众所周知域名解析会先查找 hosts 文件，如未找到才会使用 DNS，因此该方法是将 WSL 的 IP 和自定义的域名添加到 Windows 的 hosts 文件，访问时只需访问自己设定的域名。

实施思路类似于 DDNS 的 “本机 IP 变化，修改域名解析记录”，需要做到 “WSL IP 变化，修改 hosts 文件”，而我们知道 WSL IP 变化其实就是指 WSL 启动，所以最终需求变为了：WSL 启动时将 IP 写入 Windows 的 hosts 文件。

从这个需求开始，又衍生出了两个思路

在 Windows 上完成该过程，具体方法是为 WSL 启动的事件绑定自定义任务，该任务通过在 WSL 中执行ifconfig加以正则匹配获取 IP，将其写入到 hosts 文件中；

在 WSL 上完成该过程，具体方法是添加开机自启脚本，在该脚本中通过任意手段获取本机 IP，并将其写入到 /mnt/c/Windows/System32/drivers/etc/hosts （因为 Windows 的盘符会自动挂载到 WSL 的 /mnt 下）

思路 1

思路 1 的核心是自定义任务，具体的工作流程可以通过很多手段实现。比较简单的是 shayne/go-wsl2-host，该项目会自动添加在 WSL 启动时触发的自定义任务，理论上装上即可用（可惜在我这里没有正常运行，不知道是什么原因）。

思路 2

思路 2 的实现较少，因为在过去 WSL 中没有一种行之有效的 “开机自启” 方法。但该障碍已随着 WSL 对 systemd 的支持而消失不见，因此我手撸了一个采用这种方式的项目。

要使用该项目，对于 Arch Linux：

确保 WSL 能够正常读写 /mnt/c/Windows/System32/drivers/etc/hosts 文件；

下载 release 中的 .pkg.tar.zst 文件并使用sudo pacman -U安装；

使用sudo systemctl enable --now wah.service启用服务。

对于其它发行版，仅需把上述的第二个流程替换为手动安装：

Copy
install -D -m 755 $srcdir/wah $pkgdir/usr/bin/wah
install -D -m 755 $srcdir/wah.service $pkgdir/usr/lib/systemd/system/wah.service
install -D -m 755 $srcdir/domains $pkgdir/etc/wah/domains

其它步骤完全相同。

该项目默认会使用的域名是 arch.wsl，如果需要自定义，可编辑 /etc/wah/domains 文件，对于多个自定义域名，请使用单个空格分割。

该项目会自动在 hosts 文件底部添加 WSL 的地址，并在每次 WSL 启动时自动更新：