ssh 远程连接 wsl2 主机

2022 年 07 月 04 日

这段时间离职在家,没什么具体事情好做,于是自己给自己写点工具玩。

时间来到七月,神兽们都回家了,要跟我抢我的日常用机来玩游戏。没办法,拿了台旧机器,开始研究如何远程连接到原来主机上的wsl2环境。

本质上,wsl2是一台虚拟机,其网络是通过NAT方式,连接到主机上的vEthernet (WSL)接口。因此直接的解决思路就很简单,使用windows 11的端口转发,并且打开防火墙就可以。参考这篇文章即可。但这种方式有个重要的问题就是,vEthernet (WSL)接口和wsl2的ip都是动态创建的,每次启动时都会改变。换句话说,每次重启wsl2,都需要重新设定端口转发和防火墙。就算用脚本,这也是要逼死强迫症患者的。

但这里还有另外一种思路,也是上一篇文章的作者提出来的,文章在这里。其原理是:

  • 启用windows本身的ssh,使用windows的账号密码进行验证
  • 将windows的ssh所使用的终端,直接设置为bash

作者提出的几条命令其实都是微软官方提供,没什么不安全的,原始链接在这里。命令如下:

## 以下命令需要在 Admin 权限的 PowerShell 中执行

# 安装 OpenSSH Client
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

# 安装 OpenSSH Server
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

# 启动 sshd 服务
Start-Service sshd

# 建议:设置 sshd 自动启动
Set-Service -Name sshd -StartupType 'Automatic'

# 防火墙应该自动配置完成,使用下面命令验证
if (!(Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue | Select-Object Name, Enabled)) {
    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."
}

# 将默认 shell 设置为 bash
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\WINDOWS\System32\bash.exe" -PropertyType String -Force

注意,上面的命令其实无需全部执行,根据自己的需求选择即可,比如我一般就不会把sshd自动打开。另外,Start-Service sshd其实也可以用net start sshd代替。

启动sshd之后,就可以在其他主机上用ssh连接到wsl2主机了,注意账号密码应该使用windows主机的账号密码,而不是wsl2主机的账号密码。

下一步就是使用公钥免密登录。几个关键点:

  • windows主机上的配置文件在C:\ProgramData\ssh\sshd_config,此配置文件中指定,如果使用admin账户中的用户,则需要将公钥加入C:\ProgramData\ssh\administrators_authorized_keys
  • 需要编辑C:\ProgramData\ssh\administrators_authorized_keys的权限,删除继承,只把需要使用的账户和SYSTEM账户加上。后者其实就是sshd服务的进程所有者。

如果再进一步尝试,会发现此时无法使用nautilus连上wsl2的文件系统。继续研究了一下,问题出在协议上。nautilus使用的是sftp协议,这时候需要修改C:\ProgramData\ssh\sshd_config配置文件:

## 找到下面这一行并注释掉
#Subsystem      sftp    sftp-server.exe
## 改成
Subsystem       sftp    /usr/lib/openssh/sftp-server

这样就可以正常使用了。

Top