WSL Ubuntu 18.04 SSH远程连接失败?WSL 1/2网络配置与端口转发全解析

发布时间:2026/10/20 5:17:14
WSL Ubuntu 18.04 SSH远程连接失败?WSL 1/2网络配置与端口转发全解析 1. 从一次远程连接失败说起WSL网络模型的特殊性很多人第一次在Windows 10上装完WSLWindows Subsystem for Linux选的是Ubuntu 18.04这个经典版本装完SSH服务、改完配置、在本机用ssh localhost测试一切正常结果换到另一台机器或者用手机上的SSH客户端去连直接超时。这个场景我遇到过不止一次身边做嵌入式开发、后端调试的朋友也踩过同样的坑。问题的根源不在于SSH本身配置错了而在于WSL的网络模型和一台独立虚拟机、一台物理Linux服务器完全不同。WSL 1本质上是一个由Windows内核提供的兼容层它没有自己独立的内核网络栈是和Windows宿主共享的。WSL 2虽然用上了轻量级虚拟机但默认走的是NAT模式WSL实例处在一个内部虚拟网络里Windows宿主相当于这个网络的网关。这就导致两个后果第一WSL里的服务监听地址如果只绑在127.0.0.1那只有WSL内部能访问第二即使绑到了0.0.0.0外部机器也无法直接路由到这个内部地址必须经过端口转发或者网络模式调整。这篇文章面向的是已经在Windows 10上跑起WSL Ubuntu 18.04、想让局域网内其他设备比如另一台笔记本、手机、平板通过SSH连进来的开发者。我会把WSL 1和WSL 2两种情况分开讲因为它们的处理方式差别很大混在一起讲只会让人更晕。同时我会补充一些实际排查中用到的命令和判断思路这些是官方文档里往往一笔带过、但真正卡住人的地方。提示动手之前先确认自己用的是WSL 1还是WSL 2命令是wsl -l -v。这个信息决定了后面走哪条路别跳过。2. 先搞清楚你面对的是WSL 1还是WSL 22.1 两种版本的网络行为差异WSL 1的网络是和Windows宿主共享的也就是说WSL里监听的端口在Windows上看起来就像是本机监听的端口。理论上只要WSL里的服务绑到了0.0.0.0局域网内其他机器访问Windows宿主的IP加端口就能直接打到WSL里的服务上。听起来很美好但实际中经常失败原因通常是Windows防火墙拦截或者服务只绑了回环地址。WSL 2则完全是另一套逻辑。它跑在一个轻量级虚拟机里拥有独立的虚拟网卡IP地址是每次启动动态分配的通常在172.x.x.x这个段。Windows宿主和WSL 2之间通过一个虚拟交换机通信外部机器根本不知道这个172网段的存在。所以WSL 2下想让外部连进来必须做端口转发把Windows宿主的某个端口映射到WSL 2实例的对应端口上。2.2 一条命令确认版本与网络信息在Windows的PowerShell或者CMD里执行wsl -l -v输出里会有一列VERSION显示1或者2。接着进入WSL内部执行ip addr show eth0或者老一点的命令ifconfig。WSL 2会看到一个类似172.20.xxx.xxx的地址WSL 1看到的地址通常和Windows宿主在同一网段甚至就是宿主IP的某种映射。把这两个信息记下来后面配置端口转发或者防火墙规则时要用。我习惯在WSL里再跑一句hostname -I快速拿到当前IP因为WSL 2每次重启IP都可能变这个细节后面会专门讲怎么处理。2.3 为什么Ubuntu 18.04这个版本要单独提Ubuntu 18.04是WSL早期用户装得最多的版本之一它默认的SSH服务配置和后来的20.04、22.04有一些细微差别。比如18.04的openssh-server装完后/etc/ssh/sshd_config里PasswordAuthentication默认是注释掉的实际生效值是yes但很多人会误以为要手动打开。另外18.04的sshd服务在WSL里不会自动启动因为WSL默认不跑systemd除非你手动配了所以每次重启WSL都要手动拉起SSH服务。这些点在后面对应章节会展开。3. WSL 1下的SSH远程连接配置路径3.1 让sshd监听正确的地址默认情况下Ubuntu的SSH服务会监听所有网络接口也就是0.0.0.0。但有些情况下配置文件里可能被改成了只监听127.0.0.1。打开配置文件sudo nano /etc/ssh/sshd_config找到ListenAddress这一行。如果它被取消注释并写成了127.0.0.1那外部永远连不进来。正确的做法是把它注释掉或者写成0.0.0.0。注释掉时sshd默认监听所有地址这是最省事的做法。同时确认Port这一行默认是22。如果你改成了其他端口记得后面所有操作都用新端口。改完保存重启SSH服务sudo service ssh restart在WSL 1里service命令是可用的因为WSL 1对init脚本的支持比较直接。重启后用ss -tlnp | grep 22确认监听地址是0.0.0.0:22或者:::22而不是127.0.0.1:22。3.2 Windows防火墙的放行规则WSL 1的服务端口在Windows看来就是本机端口所以Windows防火墙会按本机入站规则来处理。默认情况下Windows防火墙会拦截来自局域网的入站连接。你需要手动加一条入站规则允许TCP 22端口。在PowerShell里以管理员身份执行New-NetFirewallRule -DisplayName WSL SSH -Direction Inbound -Protocol TCP -LocalPort 22 -Action Allow这条命令创建一条允许TCP 22入站的规则。执行完可以用Get-NetFirewallRule -DisplayName WSL SSH确认规则存在。注意有些第三方安全软件会接管Windows防火墙这种情况下系统防火墙规则可能不生效需要在安全软件里单独放行。我遇到过装某款安全套件后系统防火墙规则加了也没用最后是在安全软件的网络防护里把22端口加白才通。3.3 从外部机器验证连接在另一台机器上执行ssh usernamewindows_host_ipwindows_host_ip是Windows宿主在局域网里的IP用ipconfig能看到。如果连不上先在Windows宿主上用ssh usernamelocalhost测试确认SSH服务本身是活的。然后在WSL里用ssh usernamewindows_host_ip测试这一步能排除WSL内部到宿主的通路问题。最后再从外部机器测逐层缩小范围。这个分层排查的思路很关键。很多人一上来就从外部连失败了不知道是SSH没起来、监听地址不对、还是防火墙拦了。按WSL内部→Windows宿主→局域网外部这个顺序走每一步都能定位到具体环节。4. WSL 2的端口转发绕不开的一步4.1 为什么WSL 2必须做端口转发WSL 2的虚拟网卡地址是内部地址局域网里的其他机器没有到这个网段的路由。Windows宿主虽然能访问WSL 2但外部机器访问的是Windows宿主的IP流量到了宿主之后如果没有转发规则宿主不知道该把包交给谁。端口转发就是告诉Windows凡是发到我某个端口的流量都转给WSL 2实例的对应端口。Windows自带的netsh工具可以做这件事命令是netsh interface portproxy add v4tov4 listenport22 listenaddress0.0.0.0 connectport22 connectaddress172.20.xxx.xxx这里的connectaddress要换成你WSL 2实例的实际IP。listenaddress0.0.0.0表示监听所有网络接口这样局域网和本机都能访问。4.2 获取WSL 2动态IP的可靠方法WSL 2的IP每次重启都会变手动去查再改转发规则太麻烦。我常用的做法是在WSL里跑一条命令拿到IP然后在PowerShell里自动更新转发规则。在WSL里执行hostname -I | awk {print $1}这条命令输出第一个IP地址通常就是eth0的地址。然后在PowerShell里可以写一个脚本先调用wsl hostname -I拿到IP再删掉旧的转发规则、加新的。脚本大概长这样$wslIp (wsl hostname -I).Trim().Split( )[0] netsh interface portproxy delete v4tov4 listenport22 listenaddress0.0.0.0 netsh interface portproxy add v4tov4 listenport22 listenaddress0.0.0.0 connectport22 connectaddress$wslIp把这个脚本保存成.ps1文件每次重启WSL后跑一次。如果想更省事可以设成登录时自动执行但要注意执行时机得等WSL完全启动后再跑。4.3 防火墙规则同样不能少WSL 2下外部流量先到Windows宿主的22端口所以Windows防火墙仍然要放行22端口。规则和WSL 1那节一样New-NetFirewallRule -DisplayName WSL2 SSH -Direction Inbound -Protocol TCP -LocalPort 22 -Action Allow另外WSL 2内部的Ubuntu防火墙如果装了ufw也要放行。Ubuntu 18.04默认ufw是关闭的但如果你手动开过记得sudo ufw allow 22/tcp三层防火墙——WSL内部、Windows宿主、可能的路由器——任何一层拦了都会导致连接失败。排查时逐层确认别只盯着一个地方。4.4 验证端口转发是否生效在Windows宿主上执行netsh interface portproxy show all能看到当前所有转发规则。确认22端口的规则存在且connectaddress是WSL 2当前的IP。然后在宿主上用ssh usernamelocalhost测试如果这条通了说明转发链路是好的。再从外部机器连宿主IP如果还不通问题就在防火墙或者网络层面。我踩过的一个坑是转发规则加对了但WSL 2的IP在加规则之后又变了比如WSL重启过导致规则指向了一个不存在的地址。所以每次WSL重启后务必重新确认IP并更新规则。这也是为什么我强烈建议用脚本自动化这件事。5. 那些让人抓狂的细节SSH服务自启与密钥配置5.1 Ubuntu 18.04在WSL里SSH不会自动启动WSL默认不跑systemd所以systemctl enable ssh是没用的。Ubuntu 18.04在WSL里SSH服务需要手动启动sudo service ssh start每次重启WSL比如关掉所有WSL窗口再打开或者执行wsl --shutdown后重进SSH服务都会停掉。想让它自动启动有几个办法。最简单的是在~/.bashrc或者~/.profile里加一句判断如果SSH没跑就启动它if ! pgrep -x sshd /dev/null; then sudo service ssh start fi但这样每次开终端都要输密码体验不好。更好的做法是配置sudo免密执行这一条命令在/etc/sudoers.d/下加一个文件内容类似username ALL(ALL) NOPASSWD: /usr/sbin/service ssh start这样脚本里执行sudo service ssh start就不用输密码了。注意把username换成你自己的用户名并且用visudo -f来编辑这个文件避免语法错误导致sudo不可用。5.2 密码登录还是密钥登录WSL里的Ubuntu默认允许密码登录但如果你打算长期从外部连建议换成密钥登录安全性更好也省得每次输密码。步骤是在客户端机器上生成密钥对把公钥追加到WSL里的~/.ssh/authorized_keys文件。客户端生成密钥ssh-keygen -t rsa -b 4096一路回车默认生成在~/.ssh/id_rsa和~/.ssh/id_rsa.pub。然后把公钥内容复制到WSL里mkdir -p ~/.ssh chmod 700 ~/.ssh echo 公钥内容 ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys权限设置很关键。SSH对authorized_keys和.ssh目录的权限有严格要求权限太开放会拒绝使用密钥。700给.ssh目录600给authorized_keys这是标准做法。配好之后在/etc/ssh/sshd_config里确认PubkeyAuthentication yes然后重启SSH服务。客户端用ssh -i ~/.ssh/id_rsa usernamehost连接如果不再提示输密码说明密钥生效了。5.3 一个容易忽略的点WSL的默认用户WSL Ubuntu 18.04安装时会让你设一个用户名和密码这个用户就是默认登录用户。但SSH连接时用的用户名必须是这个用户不是root除非你专门配了root登录。很多人用root去连发现连不上其实是用户名搞错了。用whoami确认当前用户SSH时就用这个用户名。如果确实需要root登录得在sshd_config里把PermitRootLogin改成yes并且给root设密码。但我不建议这么做用普通用户加sudo更安全也更符合常规运维习惯。6. 排查链路实录一次完整的连接失败定位过程6.1 现象描述与初步判断有一次帮朋友处理他的WSL 2环境现象是本机ssh localhost能通另一台笔记本连过来超时。他确认过SSH服务在跑防火墙规则也加了。我先让他执行wsl -l -v确认是WSL 2。然后让他跑netsh interface portproxy show all结果发现根本没有22端口的转发规则。问题定位到第一步WSL 2没做端口转发。6.2 逐层验证的过程加上转发规则后本机ssh localhost通了但外部还是超时。接着检查Windows防火墙发现他之前加的规则只允许了专用网络而他当前网络被识别为公用网络。Windows防火墙对不同网络配置文件是分开管理的规则只对勾选的配置文件生效。把规则改成同时适用于专用和公用网络后外部连接成功。这个案例里有两个典型坑一是WSL 2忘了端口转发二是防火墙规则没覆盖当前网络配置文件。排查时按WSL内部服务→Windows转发→Windows防火墙→外部网络这个顺序走每一步都有对应的验证命令能快速定位。6.3 常用排查命令速查检查项命令预期结果WSL版本wsl -l -v显示1或2WSL内SSH监听ss -tlnp | grep 22监听0.0.0.0:22WSL IPhostname -I172.x.x.xWSL 2端口转发规则netsh interface portproxy show all有22端口规则防火墙规则Get-NetFirewallRule -DisplayName WSL SSH规则存在且启用本机连通性ssh userlocalhost能登录宿主到WSLssh userwsl_ip能登录这张表我建议存下来每次出问题按顺序过一遍基本能覆盖九成以上的连接失败场景。6.4 网络切换后的规则失效问题还有一个隐蔽的坑笔记本电脑在公司和家里之间切换网络配置文件会变。如果防火墙规则只对专用网络生效到了公司网络被识别为公用时规则就不生效了。解决办法是在创建规则时同时指定-Profile Domain,Private,Public或者事后用Set-NetFirewallRule修改。我现在的习惯是创建规则时直接带上所有配置文件省得后面来回改。7. 让连接更稳的几个进阶做法7.1 固定WSL 2的IPWSL 2的IP动态变化是端口转发最大的麻烦。除了每次重启后跑脚本更新还有一种思路是在WSL 2的配置里指定静态IP。不过这需要修改WSL的启动脚本在WSL启动时用ip addr add给eth0加一个固定地址。具体做法是在/etc/init.wsl或者通过Windows的WSL启动钩子来执行。这个方案稍微复杂而且不同WSL版本行为有差异我一般还是推荐用脚本自动更新转发规则更简单可靠。7.2 用Windows任务计划自动更新转发把前面那个PowerShell脚本注册成任务计划触发器设为登录时和WSL启动后这样每次开机或WSL重启转发规则都会自动刷新。任务计划里要注意用最高权限运行因为netsh改转发规则需要管理员权限。另外脚本里最好加个延迟等WSL完全起来再执行否则wsl hostname -I可能拿不到IP。7.3 考虑用SSH配置文件简化连接在客户端机器的~/.ssh/config里加一段Host wsl-dev HostName windows_host_ip User your_username Port 22 IdentityFile ~/.ssh/id_rsa之后直接ssh wsl-dev就能连不用每次敲一长串。如果Windows宿主IP也会变可以在路由器里给宿主机器设个静态DHCP分配或者用主机名代替IP。7.4 关于WSL 2的镜像网络模式较新版本的WSL 2支持一种叫镜像网络的模式开启后WSL 2的网络会和Windows宿主更紧密地集成局域网访问会简化很多不再需要手动端口转发。开启方式是在用户目录下创建.wslconfig文件写入[wsl2] networkingModemirrored然后wsl --shutdown重启WSL。这个模式下WSL里的服务监听端口会直接反映到Windows宿主上外部访问就像访问宿主本机服务一样。不过这个特性对WSL版本有要求Ubuntu 18.04本身没问题但Windows端的WSL组件需要更新到较新版本。如果你的环境支持这是最省心的方案值得一试。注意镜像网络模式下防火墙行为可能和默认模式不同如果开启后连不上先检查Windows防火墙对相关端口的放行情况。8. 我个人的几条实操心得折腾WSL的SSH远程连接这些年有几个体会比较深。第一永远先确认WSL版本1和2的处理路径完全不同搞错版本会白费很多时间。第二端口转发和防火墙是两件事缺一不可而且防火墙规则要确认覆盖了当前网络配置文件。第三WSL 2的IP会变任何手动配置的方案都要考虑这个变量能自动化的尽量自动化。另外Ubuntu 18.04虽然老但在WSL里跑得很稳SSH相关的坑基本就是上面这些。如果你用的是更新的Ubuntu版本SSH配置逻辑是一样的只是systemd支持更好服务自启会方便一些。最后分享一个小技巧在WSL里执行sudo service ssh status可以快速看SSH服务状态比翻日志快得多。每次连不上先跑这一条能省不少事。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询