Skip to content

如何在局域网的其他主机上中访问本机的WSL2 ​

本文为转载,来源为知乎Kingdo的如何在局域网的其他主机上中访问本机的WSL2

PS,更新采用追加式,不会修改原文,补充内容按时间放在文尾

更新日期概述
2019年10月25日发布原文
2021年10月28日ssh 连接失败: ssh_exchange_identification
2021年10月28日使用wslpp工具

原文 ​

前言 ​

WSL2 可以认为是一个运行在超轻的虚拟机当中的Linux系统. Windows中创建了一个虚拟的网卡,通过网桥(我估计)的方式与WSL相连接,网卡信息如下:

WSL 网卡:

WSL 网卡

Windows 虚拟网卡:

Windows 虚拟网卡

但是麻烦的, 每次重启WSL2, 其IP地址都会被重置, 这将带来无穷的麻烦!

好在, 在18945之后的版本中, 微软改进了WSL2, 使我们可以使用localhost, 访问WSL的网络服务:

在 wsl2 中开启一个web服务:

在 wsl2 中开启一个web服务

在windows主机中访问:

在windows主机中访问

我们也可以在PowerShell中, 直接使用ssh连接:

在PowerShell中ssh连接WSL2:

在PowerShell中ssh连接WSL2

但是如果我们希望在局域网的其他主机上直接访问WSL2, 是无法直接访问的(WSL1可以).

操作步骤 ​

概要 ​

  1. 打开防火墙的指定端口
  2. 配置端口转发规则

下以22号端口为例, 实现ssh连接, 其他如80端口方式一样

一. 开放防火墙端口 ​

1. 找到Windows 防火墙的设置页面, 点击高级设置 ​

高级设置

2. 入栈规则 -> 新建规则 -> 端口 -> 下一页 ​

下一页

3. TCP 特定本地端口, 输入22, 即想要开放的端口 ​

想要开放的端口

4. 允许连接 ​

允许连接

5. 指定可用域 ​

指定可用域

6. 添加描述(自己定义) ​

添加描述

7. 查看验证 ​

查看验证

二. 配置端口转发 ​

1. 用管理员方式打开PowerShell ​

用管理员方式打开PowerShell

2. 键入指令 ​

shell
netsh interface portproxy add v4tov4 listenport=22 listenaddress=0.0.0.0 connectport=22 connectaddress=localhost

其中:

listenport, 表示要监听的 Windows 端口

listenaddress, 表示监听地址, 0.0.0.0 表示匹配所有地址, 比如Windows 既有Wifi网卡, 又有有线网卡, 那么访问任意两个网卡, 都会被监听到,当然也可以指定其中之一的IP的地址

connectaddress ,要转发的地址, 这里设置为localhost, 是因为,我们可以通过localhost来访问WSL2, 如果暂不支持, 这里需要指定为 WSL2的IP地址

connectport, 要转发到的端口

后记 ​

一. 端口转发的其他命令 ​

show:

shell
netsh interface portproxy show all

show

delete:

shell
netsh interface portproxy delete v4tov4 listenport=22 listenaddress=0.0.0.0

二. 避免端口冲突 ​

根据我的观察, 如果Windows本地启动了指定端口, 这时WSL2中虽然可以使用相同的端口, 但是localhost:port 将指向Windows的服务, WSL的服务将会被覆盖!

当然了, 如果我们配置了端口转发, 转发的IP是WSL的地址, 而不是localhost, 那么WSL将会覆盖Windows的服务!

因此在配置时, 特别是web服务, 需要注意!

三. 容器服务 ​

使用容器,来配置web服务,显然是最佳选择,这个时候你就会遇到本文的问题,因为你可能希望让其他主机来访问你的容器服务!

但是,我并不推荐你这么做, 更好的方式是安装docker-desktop, 即Windows版的docker, WSL2会自动连接到Windows的Docker 服务中.

此时启动的容器使用的端口和Windows的端口是"相通"的,完全不需要配置端口转发!

参考文献 ​

使用WSL访问网络应用程序

Win10系统如何在防火墙里开放端口

Windows开启端口转发功能


补充 ​

补充一 ​

连接出现了如下的这样的连接错误.:

shell
ssh_exchange_identification: read: Connection reset by peer

我研究了很久, 但是, 并没有最终确定导致的原因

这里建议将 connectaddress 指定为WSL2的IP地址,即:

shell
netsh interface portproxy add v4tov4 listenport=22 listenaddress=0.0.0.0 connectport=22 connectaddress=[WSL2 IP Address]

或者是使用ipv6的回环地址,即:

shell
netsh interface portproxy add v4tov6 listenport=22 listenaddress=0.0.0.0 connectport=22 connectaddress=::1

一个是v4tov4, 另一个是v4tov6

补充二 ​

这是评论区同学,告知的一个脚本, wslpp :

这个脚本是用go语言写的,我在这里奉上使用方法:

一、在Windows PowerShell中, 将其clone到本地:

shell
git clone https://github.com/HobaiRiku/wsl2-auto-portproxy.git

将其clone到本地

二、在WSL2中, 编译此项目,注意,是需要Go的环境的, 而且这一步骤需要在Windows的管理员模式进行

shell
 sudo apt install golang-go
 cd /mnt/c/Users/`windows-user-name`/wsl2-auto-portproxy/
 make build

编译项目

三、配置wslpp的配置文件, 在WSL中执行:

shell
mkdir /mnt/c/Users/14408/.wslpp
vim  /mnt/c/Users/14408/.wslpp/config.json

输入:
{
  "onlyPredefined": true,
  "predefined": {
    "tcp": [
      "22:22"
    ]
  },
  "ignore": {
    "tcp": [
      445
    ]
  }
}:

四、回到Windows PowerShell中, 执行:

shell
 cd .\wsl2-auto-portproxy\dist\
 .\wslpp.exe

执行

第一次执行,需要等一会,而且还要允许防火墙让wslpp访问网络的配置!

本质上,这个脚本就是开启防火墙,然后进行端口映射,只不过他会自动扫描WSL的配置,因此比我们手动自己配置映射要靠谱一些!

其实上述过程,只在windows中就可以完成, 但是毕竟Linux操作不会多复杂.

此外, WSL操作Windows的文件,是需要在管理员模式下进行的.

这方法,目前没遇到问题, 但是需要你额外软件开一个!

请勿转载