如何远程登录WSL2

使用笔记本开发时性能有限,内存容量也不支持拉起太多服务,还是使用高配 Windows PC 上的 WSL 2 开发起来比较方便。与 Linux 相比,Windows 上的 OpenSSH 服务端功能在登录验证时有着自己的特性,值得记录下。整个登录链路结构如下:

---
config:
  theme: 'base'
  themeVariables:
    darkMode: true
    fontSize: 16px
    primaryColor: '#000'
    primaryTextColor: '#fff'
    primaryBorderColor: '#02d7f2'
    lineColor: '#fcee09'
    tertiaryColor: '#0d0d0d'
    tertiaryBorderColor: '#cdcdcd'
---
flowchart LR
  subgraph Tailscale
    direction LR
    A
    B
    subgraph PC
      direction LR
      B
      C
    end
  end
  A["Laptop"] e1@-- SSH --> B["Windows"]
  B e2@-- 本地进程通信 --> C["WSL2"]
  e1@{ animate: true }
  e2@{ animate: true }

启用OpenSSH Server

Win+R 输入 powershell 后按 Ctrl+Shift+Enter,以管理员身份运行 PowerShell:

# 查询当前系统中与OpenSSH相关的可选功能的状态
PS> Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
Name : OpenSSH.Client~~~~0.0.1.0
State : Installed

Name : OpenSSH.Server~~~~0.0.1.0
State : NotPresent

# OpenSSH的客户端默认已经安装,但服务端还未安装,需要安装下
PS> Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Path :
Online : True
RestartNeeded : False

# 启动sshd服务
PS> Start-Service sshd
# 查看sshd服务状态
PS> Get-Service sshd
Status Name DisplayName
------ ---- -----------
Running sshd OpenSSH SSH Server
# 设置sshd服务自启动
PS> Set-Service -Name sshd -StartupType 'Automatic'

启动 sshd 服务后,会在 C:\ProgramData\ssh 目录下生成配置文件 sshd_config 以及多种密钥对:

C:\ProgramData\ssh\ >folded
PS> ls
目录: C:\ProgramData\ssh
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2025/9/16 15:03 logs
-a---- 2025/9/16 15:03 7 sshd.pid
-a---- 2022/5/6 14:15 2297 sshd_config
-a---- 2025/9/16 15:03 513 ssh_host_ecdsa_key
-a---- 2025/9/16 15:03 185 ssh_host_ecdsa_key.pub
-a---- 2025/9/16 15:03 419 ssh_host_ed25519_key
-a---- 2025/9/16 15:03 105 ssh_host_ed25519_key.pub
-a---- 2025/9/16 15:03 2610 ssh_host_rsa_key
-a---- 2025/9/16 15:03 577 ssh_host_rsa_key.pub

还会自动创建防火墙规则——允许 22 端口的 TCP 入站请求。可以执行下面的命令确认下该规则是否存在,如果不存在会自动创建该规则:

PS> if (!(Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue)) {
Write-Output "Firewall Rule 'OpenSSH-Server-In-TCP' does not exist, creating it..."
New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
} else {
Write-Output "Firewall rule 'OpenSSH-Server-In-TCP' has been created and exists."
}

无密码登录

开启 OpenSSH Server 服务后,我们尝试下能否登录:

$ ssh localhost
The authenticity of host 'localhost (::1)' can't be established.
ED25519 key fingerprint is SHA256:c+JdPZlkDWQ1gfd+0PM1eN7Pf123GydtvYe45qCV6j7.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'localhost' (ED25519) to the list of known hosts.
thinklong@localhost's password:
Permission denied, please try again.

由于 Windows PC 是我的个人电脑,没有为管理员用户 thinklong 设置密码,使用空密码登录会被拒绝。可以在 sshd_config 中开启与密码登录有关的配置项:

C:\ProgramData\ssh\sshd_config
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication yes # 允许密码验证
PermitEmptyPasswords yes # 允许空密码登录

把这两个配置项都设为 yes,执行 Restart-Service sshd 命令重启 sshd 服务后再次尝试登录,发现仍然要求输入密码,这就是 Windows 上特殊的地方。

在 Linux 上 sshd 会自己查 /etc/shadow,如果密码是空的就能允许该用户无密码登录。但在 Windows 上 OpenSSH 是调用 Windows 的登录 API来验证用户密码,并且在 Windows 本地安全策略(可以通过运行 secpol.msc 打开)中有这么一条策略——“账户:使用空密码的本地账户只允许进行控制台登录”,默认为启用,旨在限制空密码账户只能通过控制台本地登录(Logon Type 为 2),而 SSH 登录通过事件查看器看到它属于网络登录(Logon Type 为 3),将这条策略改为禁用才能允许 SSH 空密码登录。

Windows本地策略-空密码策略

注:家庭版系统默认不包含本地安全策略。

配置免密登录

当然无密码登录并非重点,我们需要的是免密登录。略去为 thinklong 用户创建密钥对的过程,修改配置开启免密登录——允许公钥验证并关闭密码验证:

C:\ProgramData\ssh\sshd_config
- #PubkeyAuthentication yes
+ PubkeyAuthentication yes

# To disable tunneled clear text passwords, change to no here!
- #PasswordAuthentication yes
+ PasswordAuthentication no
- #PermitEmptyPasswords no
+ PermitEmptyPasswords no

此外还注意到 sshd_config 文件存在如下配置:

C:\ProgramData\ssh\sshd_config
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys

Match Group administrators
AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

这段配置指定了免密登录用户的公钥存储位置,普通用户管理员用户使用两个不同文件进行验证。因此把 thinklong 这个管理员用户的公钥写进 ~/.ssh/authorized_keys 是无效的,正确的写入位置为 %PROGRAMDATA%\ssh\administrators_authorized_keys

做完以上操作,重启 sshd 服务后就能成功免密登录:

PS> Restart-Service sshd
PS> ssh thinklong@localhost
Microsoft Windows [版本 10.0.26100.4652]
(c) Microsoft Corporation。保留所有权利。

thinklong@SUPERPOW C:\Users\thinklong>

默认情况下 SSH 登录 Windows 后进入的是 CMD 命令行,再执行 wsl 命令即可进入 WSL 2。

修改默认Shell

设置防火墙规则:

PS> ip address | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1280 qdisc mq state UP group default qlen 1000
inet 172.30.219.137/20 brd 172.30.223.255 scope global eth0

PS> netsh interface portproxy add v4tov4 listenport=22 listenaddress=0.0.0.0 connectport=22 connectaddress=172.30.223.255

PS> netsh interface portproxy show all
侦听 ipv4: 连接到 ipv4:

地址 端口 地址 端口
--------------- ---------- --------------- ----------
0.0.0.0 22 172.30.223.255 22

参考资料

适用于 Windows 的 OpenSSH 入门

OpenSSH for Windows 中基于密钥的身份验证

帐户:限制本地帐户使用空白密码,仅限控制台登录

WSL 中的高级设置配置

如何从外部计算机通过 SSH 连接到 Windows 10 上的 WSL2

如何从外部计算机通过 SSH 轻松连接到 Windows 10 上的 Bash 和 WSL2

作者

ThinkLong

发布于

2025-09-16

更新于

2025-12-14

许可协议

评论

+