【wsl2】MacOS/Win局域网ssh连接wsl2:Ubuntu24.04 LTS
保证使用的是微软应用商店中下载的Ubuntu发行版本,本文在配置时发现若使用docker所基于的ubuntu系统配置会失败。遂采用默认的子发行版本。
可以通过微软商店下载。也可以在更新wsl2至最新版后,使用命令安装
wsl -l -o
# 安装Ubuntu-24.04(推荐长期支持版本)
wsl --install Ubuntu-24.04
# 设置默认WSL版本为2(若未设置)
wsl --set-default-version 2
# 查看已安装的发行版
wsl -l -v
# 将Ubuntu设为默认
wslconfig /setdefault Ubuntu-24.04
或请参考其他教程安装,本文默认你的子系统安装没有问题!
写在前面
why wsl2?
因为题主在跑python时,i9-13900K只调用了20%,使用wsl后可以使cpu跑满80%+。加速炼丹!
然而实验室电脑上还有同学需要使用matlab等其他工具,显然是不能卸载Windows的。
遂退而且其次使用WSL2.
win11的好处
如果你是win11,那么恭喜你,请你根据关键词:镜像网络mirrored wsl2
搜索相关教程去实现局域网ssh连接。
如: https://blog.csdn.net/jyzjut/article/details/140079778
如何查看自己的windows系统版本:
# win + r 输入: winver
如果你和题主一样,不习惯用win11,仍然是win10(190xx.xxxx版本)的钉子户(好吧,现在题主已经卸载win拥抱macOS了,这是实验室的电脑),那么根据一些教程配置.wslconfig为mirrored
后
一定会报错!因为mirrored
模式This is unfortunately by design. Mirrored networking is only supported on Windows 11!(Github找到的Issue)
开始配置之前
为了方便区分:装载ubuntu子系统的
Windows
称做宿主机,子系统称做wsl或wsl2子系统。
1. 确保宿主机和wsl2子系统能够ping通
WSL2默认的网络模式为NAT,什么是NAT?
核心作用:NAT 允许内部私有网络中的设备通过一个公共IP地址访问外部网络(如互联网)。
类比:想象你住在一栋公寓楼里,所有住户共用同一个对外地址(公网 IP),但每户有自己的房间号(私有 IP)。快递员只需将包裹送到公寓地址,再由管理员分发给具体房间。这就是 NAT 的工作方式。
如何检查 WSL2 的 IP 地址?
参考:https://www.cnblogs.com/SocialistYouth/p/16691035.html
上面的文章写的很好,强烈建议看完后继续阅读本文。
WSL2中运行:
ip addr show eth0 # 查看私有 IP(如 172.x.x.x)
Win终端中:
wsl hostname -I # 获取 WSL2 的 IP
OK,此时我们发现因为只有一个wsl2系统,所以是同一个ip地址。
那么这个类似的“公网IP”在哪里呢?
win终端运行ipconfig
WSL 172.25.224.1 就是给wsl系统分配的“公网ip”
wsl2 则可以理解为宿主机完整虚拟出来的一个完整的 Linux 虚拟机,拥有自己的逻辑上独立的网卡,也即拥有属于自己的独立网络栈。与 VMware 的 bridge 模式和 docker 的 macvlan 模式类似。
此时,按照正常思路,我们应该确保wsl2子系统172.25.233.221
与宿主机10.193.225.128
相互之间能够ping通,如果ping不同,请参考 https://www.cnblogs.com/SocialistYouth/p/16691035.html
例如我的:
#宿主机终端:
ping 172.25.233.221
#wsl2执行
ping 10.193.225.128
保证他们都能ping通再继续!
2. 确保第三方主机与宿主机ping通
参考:https://www.crifan.org/windows_10_wifi_lan_cannot_be_pinged_by_mac/
题主是用自己的macOS去连接宿主机win下的wsl2,所以,这一步也十分关键。
保证你的设备和宿主机都在一个局域网下!
#验证
#macOS执行:
ping <宿主机ip>
#宿主机执行
ping <macOS ip>
这时候,我们发现一般都ping不通。为什么?防火墙!
此时,无脑关闭所有防火墙,尝试ping,一般都能ping通了。ping不通请检查是否手动设置过ip地址,如果不会设置的话,请恢复为dhcp方式获取ip地址,此外请检查以及物理连接是否通畅。
测试成功后,如果您不放心你的宿主机裸奔,请参考https://blog.csdn.net/hitzzq508/article/details/120576464进行防火墙设置。
开始配置
- wsl2安装openssh
apt update
apt install openssh-server
可选,即登录时,宿主机可使用:ssh root@<wsl-ip>
连接
#在wsl2中开启root用户远程访问
username@localhost:/$ sudo passwd root
New password:
Retype new password:
- 配置openssh
sudo nano /etc/ssh/sshd_config
# 端口默认是22,可以改为指定的端口,此处改成3456
Port 3456
ListenAddress 0.0.0.0
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
PasswordAuthentication yes
#取消注释并修改为yes
PermitRootLogin yes
注意:此处的端口是宿主机(即安装wsl2的机器)连接wsl2的端口,与外界机器连接宿主机的接口不同。(当然,你也可以设置成同一个,为显区分,本文将设置为不同的端口号)
接下来,你会发现ubuntu22.04以上版本的系统不生效,端口还是22.具体关键词可以搜索ubuntu24.04 修改默认ssh端口失败
# 重启ssh服务
sudo service ssh restart #不生效~
# ubuntu 22.04及以上
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket #这个是关键!
# 查看端口
sudo service ssh status
- 配置防火墙
# 宿主机终端或powershell中执行:
New-NetFirewallRule -DisplayName "WSL" -Direction Inbound -InterfaceAlias "vEthernet (WSL)" -Action Allow
-
接下来,在宿主机win中测试ssh连接wsl2
打开宿主机的终端或powershell:# 这里的3456就是上面设置的端口,可以设置为其他你习惯的端口号 ssh <id>@localhost -p 3456 # 例如我就是: ssh ronchy22@localhost -p 3456
如果能够宿主机能够连接成功,可以尝试以下的配置方式,将外部连接的端口(如1758)映射到WSL2的SSH端口(3456):
# listenport=<port1> 是指其他机器连接到本机所用的端口,本文章中设置为1758 # connectport=<port2> 是指本机连接到本机wsl2所用的端口,本文章中设置为3456 # 格式如下: # netsh interface portproxy set v4tov4 listenport=<port1> connectport=<port2> connectaddress=127.0.0.1 netsh interface portproxy set v4tov4 listenport=1758 connectport=3456 connectaddress=127.0.0.1 # 查看端口转发列表,检查刚刚有无设置成功 netsh interface portproxy show all # 查看windows正在监听的端口,应该能看到所设定的端口1758正在被LISTENING netstat -ano -p tcp
- listenaddress=0.0.0.0允许所有IP访问,若需限制可改为宿主机局域网IP
- 若WSL重启导致IP变化,需动态获取IP(见步骤5解决方案)
-
在第三方如macOS测试ssh连接宿主机
macOS终端中输入下列命令,并按照提示输入密码。# macOS terminal ssh <wsl2-usrname>@<宿主机ip> -p 1758 # 例如我的:ssh ronchy22@10.193.225.128 -p 1758
此时如果macOS终端报错:
kex_exchange_identification: read: Connection reset
,
那么,请在宿主机
合适的地方,如C\User\username,或者桌面新建文本文档
,并将后缀修改为.ps1
,并以管理员权限运行,再次尝试连接,即可!$wsl_ip = (wsl hostname -I).Trim() netsh interface portproxy delete v4tov4 listenport=1758 netsh interface portproxy add v4tov4 listenport=1758 connectport=3456 connectaddress=$wsl_ip
- 此脚本动态获取WSL最新IP并更新转发规则
- 权限问题:确保Windows防火墙允许1758端口入站 (即上面的防火墙设置)
New-NetFirewallRule -DisplayName "WSL2_SSH" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 1758
端口映射逻辑详解:
很多教程都是22对22端口,所以很容易把监听端口搞混淆.
- 为何避免22对22端口? 冲突风险:Windows可能已占用22端口(如OpenSSH服务),导致转发失败
- 清晰区分:
- WSL内部端口:SSH服务实际监听的端口(如3456),需在sshd_config中设置。
- 宿主机监听端口:外部设备连接的端口(如1758),通过netsh映射到WSL的3456
- 映射关系示意图
外部设备(Mac) --> 宿主机IP:1758 --> WSL IP:3456
通过以上步骤,可实现稳定的跨设备SSH访问WSL2服务!。若需长期使用,建议结合开机自启脚本和动态IP处理,避免手动维护!
补充:一键化脚本与开机自启
- 创建PowerShell脚本 保存为auto_forward.ps1(管理员运行)
Powershell
# 获取WSL动态IP
$wsl_ip = (wsl hostname -I).Trim()
# 删除旧规则,防止冲突
netsh interface portproxy reset
# 添加SSH端口转发
netsh interface portproxy add v4tov4 listenport=1758 listenaddress=0.0.0.0 connectport=3456 connectaddress=$wsl_ip
# 开放防火墙
if (-not (Get-NetFirewallRule -DisplayName "WSL2_SSH" -ErrorAction SilentlyContinue)) {
New-NetFirewallRule -DisplayName "WSL2_SSH" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 1758
}
- 设置开机自启
将脚本放入启动文件夹(Shell:Startup),或通过任务计划程序添加开机任务.