2026/10/20 22:04:58

WSL 2 SSH远程连接实战:端口转发、桥接与镜像模式配置指南

WSL 2 SSH远程连接实战:端口转发、桥接与镜像模式配置指南 1. 先搞清楚WSL的网络模型到底怎么回事很多人装完WSLWindows Subsystem for Linux之后第一反应就是掏出另一台电脑或者手机上的SSH客户端想直接连过去。结果发现连不上然后就开始怀疑是不是SSH服务没装好、防火墙没关、端口写错了。实际上绝大多数情况下问题根本不在SSH本身而在于WSL的网络架构跟一台独立虚拟机完全不是一回事。WSL 1和WSL 2在网络层面有本质区别。WSL 1是微软早期实现的一种系统调用翻译层Linux的进程直接跑在Windows内核之上网络栈跟Windows主机是共享的。也就是说WSL 1里的Linux发行版跟Windows用的是同一套网络接口IP地址就是Windows主机的IP端口也是直接绑在主机上的。这种情况下SSH服务只要在WSL里跑起来外部设备直接连Windows主机的IP就能连上基本不需要额外配置。但WSL 2就完全不一样了。WSL 2本质上是一个轻量级的虚拟机跑在Hyper-V的虚拟化层之上拥有自己独立的内核和独立的网络栈。微软给WSL 2分配了一个虚拟网卡这个网卡通过NAT网络地址转换的方式跟Windows主机通信。WSL 2拿到的是一个内部私有IP通常是172.x.x.x这个网段而Windows主机在WSL 2看来是它的网关。外部设备根本不知道这个172网段的存在自然也就无法直接访问WSL 2里的服务。这就是为什么很多人按照网上教程装完openssh-server、改完sshd_config、启动服务之后从局域网里另一台机器SSH过去死活连不上。不是SSH没配好是网络路径根本不通。你要么做端口转发要么做网络桥接要么换一种访问方式。下面我会把几种主流方案都拆开讲清楚包括每种方案的适用场景、具体操作步骤、以及我实际踩过的坑。提示在动手之前先确认你用的是WSL 1还是WSL 2。在PowerShell里执行wsl -l -v输出里会显示每个发行版对应的版本号。这个信息决定了你后面该走哪条路。2. 方案选型端口转发、桥接网络还是换思路搞清楚网络模型之后解决思路其实就三条路端口转发、网络桥接、以及绕开网络层用其他方式访问。这三条路各有优劣适用的场景也不一样我逐个分析一下选型逻辑。2.1 端口转发方案最通用但最繁琐端口转发port forwarding的思路是在Windows主机上监听一个端口然后把所有发到这个端口的流量转发到WSL 2实例的对应端口上。这样外部设备只需要连Windows主机的IP和端口就能间接访问到WSL 2里的SSH服务。这个方案最大的好处是通用性强不需要改WSL的网络模式不需要额外的软件用Windows自带的netsh命令就能搞定。缺点是WSL 2的IP地址每次重启都会变所以你每次重启电脑或者重启WSL之后都得重新查IP、重新配转发规则。对于偶尔用一次的场景还能忍天天用的话就很烦。2.2 桥接网络方案一劳永逸但有门槛桥接网络的思路是让WSL 2实例直接桥接到物理网卡上从路由器获取一个跟Windows主机同网段的IP地址。这样WSL 2就像局域网里一台独立的机器一样外部设备可以直接访问它的IP不需要任何转发。这个方案的好处是一劳永逸配好之后WSL 2的IP虽然也可能变但至少跟主机在同一网段SSH直连就行。缺点是实现起来比较麻烦需要修改WSL的配置文件而且不同Windows版本对桥接模式的支持程度不一样。另外桥接模式下WSL 2跟Windows主机之间的网络隔离会发生变化某些依赖localhost通信的开发工具可能会出问题。2.3 绕开网络层用Windows主机做跳板还有一条路是不直接访问WSL 2而是先SSH到Windows主机再从Windows主机SSH到WSL 2。Windows 10本身可以装OpenSSH Server装好之后外部设备先连Windows然后在Windows的终端里再执行ssh userwsl-ip跳到WSL里。这个方案的好处是不需要做端口转发也不需要改WSL网络模式。缺点是每次要多跳一次操作上多了一步。而且Windows的OpenSSH Server配置本身也有坑比如默认shell是cmd而不是bash需要额外改注册表。适合那些本来就需要经常连Windows主机的场景。方案适用场景优点缺点端口转发偶尔远程访问不想改配置通用、无需额外软件每次重启需重配IP会变桥接网络频繁远程访问追求稳定一劳永逸直连体验好配置复杂可能影响其他工具Windows跳板已需连Windows主机不改WSL网络多一跳Windows SSH也需配置我个人的建议是如果你只是偶尔需要从另一台设备连一下WSL用端口转发就够了五分钟搞定。如果你是天天要连、把WSL当远程开发机用那值得花时间把桥接网络配好。下面我把端口转发和桥接网络两种方案的具体操作都详细写一遍。3. 端口转发方案完整实操端口转发是我用得最多的方案因为大部分时候我只是临时需要从笔记本连一下台式机上的WSL。整个流程分四步确认WSL的IP、确认SSH服务在跑、配转发规则、测试连接。3.1 确认WSL 2的IP地址和SSH服务状态先打开WSL终端执行ip addr show eth0或者hostname -I拿到WSL 2实例的IP地址。通常长这样172.28.xxx.xxx。记下这个IP后面配转发要用。然后确认SSH服务是不是在跑。执行sudo service ssh status如果显示running就说明服务已经起来了。如果没有先执行sudo apt update sudo apt install openssh-server -y安装然后sudo service ssh start启动。这里有个细节要注意Ubuntu 18.04默认的SSH配置里PasswordAuthentication可能是被注释掉的默认值是yes所以用密码登录一般没问题。但如果你之前改过配置最好检查一下/etc/ssh/sshd_config里这几项Port 22 PasswordAuthentication yes PermitRootLogin prohibit-password改完之后记得sudo service ssh restart重启服务。另外Ubuntu 18.04的WSL里SSH服务不会开机自启每次重启WSL都要手动启动或者写个脚本加到.bashrc里。3.2 用netsh配置端口转发规则回到Windows这边以管理员身份打开PowerShell。执行下面这条命令把Windows主机的2222端口转发到WSL 2的22端口netsh interface portproxy add v4tov4 listenport2222 listenaddress0.0.0.0 connectport22 connectaddress172.28.xxx.xxx这里的listenaddress0.0.0.0表示监听所有网络接口这样局域网里其他设备才能连进来。如果你只想本机访问可以改成127.0.0.1。connectaddress填你刚才查到的WSL 2的IP。配完之后用netsh interface portproxy show all查看规则是否生效。然后还需要在Windows防火墙里放行2222端口执行netsh advfirewall firewall add rule nameWSL SSH dirin actionallow protocolTCP localport2222这两步做完从局域网另一台机器执行ssh usernamewindows-ip -p 2222就应该能连上了。3.3 解决IP变化导致转发失效的问题WSL 2的IP每次重启都会变这是端口转发方案最大的痛点。我试过几种应对方式最靠谱的是写一个PowerShell脚本每次开机或者需要的时候跑一下自动查IP、删旧规则、加新规则。$wslIp (wsl hostname -I).Trim().Split( )[0] netsh interface portproxy delete v4tov4 listenport2222 listenaddress0.0.0.0 netsh interface portproxy add v4tov4 listenport2222 listenaddress0.0.0.0 connectport22 connectaddress$wslIp Write-Host Forwarding 2222 - $wslIp:22把这个脚本保存成.ps1文件每次重启WSL之后右键用管理员权限运行一下就行。更进一步的做法是把它加到Windows的任务计划里开机自动执行。不过要注意WSL实例本身也需要先启动脚本才能拿到IP所以任务计划里最好加个延迟或者先执行wsl echo ok唤醒WSL。注意wsl hostname -I返回的IP可能包含多个地址取第一个通常是eth0的地址。如果你改过WSL的网络配置最好用wsl ip addr show eth0来精确获取。3.4 测试连接与常见报错处理配好之后从另一台机器测试如果连不上按下面的顺序排查先在Windows主机上执行ssh usernamelocalhost -p 2222看本机能不能连。本机能连说明转发规则和SSH服务都没问题问题出在防火墙或者网络层。本机连不上检查netsh interface portproxy show all里的IP是不是当前WSL的IP。IP变了规则就失效了。检查Windows防火墙有没有放行2222端口。可以临时关掉防火墙测试一下确认是防火墙问题再针对性加规则。检查WSL里的SSH服务是不是在跑sudo service ssh status看一下。如果提示Connection refused通常是SSH服务没起来或者端口不对。如果提示Connection timed out通常是防火墙或者网络路径问题。我踩过的一个坑是Windows上装了某些安全软件会拦截netsh的端口转发规则导致规则看起来配好了但实际不生效。遇到这种情况先把安全软件临时禁用测试一下确认是它的问题之后把2222端口加到白名单里。4. 桥接网络方案深入配置如果你受不了每次重启都要重配转发规则桥接网络是更彻底的解决方案。核心思路是让WSL 2实例直接使用物理网卡从路由器拿一个跟Windows主机同网段的IP。4.1 通过.wslconfig启用桥接模式在Windows用户目录下创建或编辑.wslconfig文件路径是C:\Users\你的用户名\.wslconfig。写入以下内容[wsl2] networkingModebridged vmSwitch你的物理网卡名称vmSwitch填你的物理网卡名称可以在控制面板 - 网络和共享中心 - 更改适配器设置里看到。比如以太网或者Wi-Fi。注意这里填的是网卡的连接名称不是网卡型号。改完之后执行wsl --shutdown关闭WSL再重新打开。这时候WSL 2应该会从路由器获取一个跟主机同网段的IP。用ip addr show eth0确认一下如果看到的是192.168.x.x或者10.x.x.x这种跟主机同网段的地址就说明桥接成功了。4.2 桥接模式下的SSH配置与验证桥接成功之后SSH的配置就简单了。确保WSL里的SSH服务在跑然后从局域网另一台机器直接ssh usernamewsl-ip就行不需要任何端口转发。但桥接模式有几个坑要注意。第一不是所有Windows 10版本都支持networkingModebridged这个特性是较新版本才加入的。如果你的.wslconfig改了之后没效果先执行wsl --version看看版本号太老的话需要先更新WSL内核。第二桥接模式下WSL 2跟Windows主机之间的localhost通信可能会失效比如你在WSL里跑了个Web服务想在Windows浏览器里用localhost访问可能就不行了得用WSL的IP访问。第三某些企业网络环境对桥接模式有限制可能会拿不到IP。4.3 桥接模式的替代思路用host网络模式如果你的WSL版本不支持桥接模式还有一个折中方案是让WSL 2共享Windows主机的网络栈。在.wslconfig里写入[wsl2] networkingModemirrored镜像模式mirrored是比桥接更新的特性它让WSL 2直接镜像Windows主机的网络接口localhost通信也能正常工作。这个模式对版本要求更高但体验是最好的。配好之后WSL 2里的服务直接绑在主机IP上外部设备连主机IP就能访问跟WSL 1的体验类似。我实测下来镜像模式在较新的Windows 10 22H2版本上表现很稳SSH直连没有任何问题而且localhost转发也正常。如果你的版本支持我强烈建议用这个模式而不是桥接。5. 常见问题排查与避坑经验这一块是我踩坑最多的地方很多问题网上教程不会讲但实际用的时候一定会遇到。我整理成速查表方便你对照排查。5.1 SSH连接失败问题速查表现象可能原因排查方法解决方案Connection refusedSSH服务未启动sudo service ssh status启动服务并设为自启Connection timed out防火墙拦截临时关防火墙测试放行对应端口转发规则不生效WSL IP已变化netsh portproxy show all重新配置转发规则本机能连外部不能连listenaddress不对检查是否为0.0.0.0改为0.0.0.0密码正确但登录失败配置禁用了密码登录检查sshd_config改PasswordAuthentication连接后立即断开shell配置有问题查看/var/log/auth.log修复用户shell配置5.2 那些教程不会告诉你的细节第一个坑是WSL里的SSH服务默认不会开机自启。Ubuntu 18.04的WSL用的是SysV init而不是systemd所以systemctl enable ssh是没用的。你得用sudo service ssh start手动启动或者把启动命令加到.bashrc里。但加到.bashrc有个问题每次打开新终端都会尝试启动一次虽然重复启动不会报错但会拖慢终端启动速度。更好的做法是写个判断只在服务没跑的时候启动。第二个坑是Windows防火墙的入站规则。很多人只加了netsh的portproxy规则忘了加防火墙规则结果本机能连外部不能连。而且Windows防火墙有时候会有多个配置文件域、专用、公用你加的规则可能只对其中一个生效。最稳妥的做法是在防火墙高级设置里手动新建入站规则把TCP 2222端口对所有配置文件都放行。第三个坑是WSL 2的IP在wsl --shutdown之后会变但如果你只是关闭终端窗口而没有执行shutdownWSL实例其实还在后台跑IP不会变。所以如果你发现转发突然失效了先确认是不是执行过shutdown或者重启过电脑。第四个坑是关于SSH密钥的。如果你用密钥登录而不是密码要把公钥放到WSL里的~/.ssh/authorized_keys并且确保权限正确.ssh目录是700authorized_keys是600。权限不对的话SSH会拒绝使用密钥而且报错信息很隐晦只会在日志里显示。5.3 性能与稳定性优化建议端口转发方案在高频使用下会有轻微的性能损耗因为多了一层NAT转换。如果你只是敲命令感觉不出来。但如果你要通过SSH传大文件或者做端口转发跑图形界面可能会有影响。这种场景下桥接或镜像模式更合适。另外WSL 2的内存和CPU分配也会影响SSH的响应速度。默认情况下WSL 2会占用最多50%的物理内存如果你主机内存不大WSL里跑的东西又多SSH响应会变慢。可以在.wslconfig里限制内存和CPU[wsl2] memory4GB processors2这个配置根据你主机的实际配置调整一般给WSL分配4GB内存和2个CPU核心就够日常开发用了。提示修改.wslconfig之后必须执行wsl --shutdown再重新打开WSL才会生效。直接关终端窗口是不行的。6. 我个人的实操体会与建议折腾WSL的SSH远程连接这件事我从WSL刚出来的时候就开始用中间踩过的坑不计其数。最大的体会是不要一上来就照着网上的教程一步步抄先搞清楚自己的WSL是1还是2网络模型是什么然后再选方案。很多人卡住就是因为用WSL 2的机器去套WSL 1的教程怎么配都不对。如果让我给一个最省心的方案我会推荐优先尝试镜像模式networkingModemirrored前提是你的WSL版本支持。这个模式配好之后基本不需要维护SSH直连、localhost转发都正常体验最接近原生Linux。如果版本不支持退而求其次用端口转发加自动脚本虽然每次重启要跑一下脚本但胜在稳定可控不依赖WSL的版本特性。还有一个建议是不管用哪种方案都先把SSH服务设成开机自启。WSL里没有systemd但你可以用sudo visudo加一行%sudo ALL(ALL) NOPASSWD: /usr/sbin/service ssh start然后在.bashrc里加一行sudo service ssh start /dev/null 21这样每次打开终端都会自动启动SSH而且不需要输密码。这个技巧我用了很久很稳。最后再分享一个小技巧如果你经常需要在多台设备之间切换连接WSL可以在SSH客户端里配好Host别名把IP、端口、用户名都写进去这样每次只需要ssh wsl就能连上不用记那些乱七八糟的IP和端口。具体就是在~/.ssh/config里加一段Host wsl HostName 192.168.1.100 Port 2222 User yourname这样不管你在哪台设备上只要配置文件同步了一条命令就能连上。配合端口转发脚本或者镜像模式日常使用体验跟连一台独立服务器没什么区别。