前言

今天为了测试html,用了nodejs的http-server命令,当然有了WSL那肯定是在WSL2中启动http-server,启动后问题就来了,8080端口是无法在局域网里访问的,但是windows宿主机是可以通过127.0.0.1:8080来访问到

WSL2相关

WSL2用的是hyper-v 相当于一个虚拟机,但是在网络那块就有点奇怪了,wsl2与windows中会有一个专有的ip。

举例

WSL2专用ip为:172.31.58.132,windows的公网ip为:192.168.167.82
那么问题来了 我wsl2启动了一个http服务 端口为8080,如何在局域网中访问它?

一开始想的办法是让wsl2直接在局域网获取一个新的ip 比如192.168.167.83,试着给wsl2用了固定ip后也是不行的,连wsl2本身的网络都断开了,看了一下wsl2官方的issue发现官方目前是不支持wsl2直接获取ip的,v2ex上有老哥试着用网桥来解决这个问题,但是看最后的评论结果还是没有成功,于是目前的办法就比较hack了,局域网机器访问windows宿主机,windows宿主机转发端口至wsl2,虽然流程很简单,网络上也有老哥给出了解决方案,比较常见的指令就是 netsh interface portproxy add v4tov4 listenport=8080 connectaddress=127.0.0.1 connectport=8080 listenaddress=* protocol=tcp,但是这段指令还是有个问题我转发的ip是127.0.0.1 这里很明显转发到的是windows宿主机的ip而不是wsl2的ip。但是有个疑问的点是 windows宿主机能够在浏览器直接访问127.0.0.1:8080来访问到wsl2中的http服务。于是事情就变成了 我转发到127.0.0.1是不行的,必须转发到wsl2内部ip也就是172.31.58.132,这里的话问题变成了 wsl2的内部ip是每次重启都会变的。
这里的解决方案为

  1. 编写windows脚本每次重启来获取wsl2的内部ip并且写入到windows的hosts中。
  2. 利用某位老哥的go脚本,老哥的go脚本实际原理还是用的1的方案,最后的解决方案变成了netsh interface portproxy add v4tov4 listenport=8080 connectaddress=ubuntu.wsl connectport=8080 listenaddress=* protocol=tcp
    也就是ubuntu.wsl为写入到hosts中的地址 。。。。

go脚本自动获取内部ip

go-wsl2-host

这个脚本主要的用处为 每次重启获取内部ip 并且会写入到windows的hosts中 这样以后在windows需要转发某些端口的时候直接转发到hosts的别名就行了,不过需要管理员权限才能运行,并且会常驻windows的启动任务中

windows自带的端口转发命令

netsh interface portproxy add v4tov4 listenport=8080 connectaddress=ubuntu.wsl connectport=8080 listenaddress=* protocol=tcp

比较简单,listenport为windows需要监听的端口,connectport为WSL2你的服务端口,如果不用转发了可以执行删除命令
netsh interface portproxy delete v4tov4 listenport=8080 protocol=tcp