SSH 免密登录 Windows
安装并启动 OpenSSH Server
在开始之前请确保你的远程 Windows 已经安装了 OpenSSH Server。打开远程 Windows 终端(管理员),运行以下命令:
# 查看可以安装的 OpenSSH Server 版本
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
# 安装 OpenSSH Server,我这里的最新版本是 0.0.1.0
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
接下来启动 OpenSSH Server:
Start-Service sshd # 启动 sshd 服务
Set-Service -StartupType Automatic sshd # 设置 sshd 服务自动启动
参考:适用于 Windows 的 OpenSSH 入门 | Microsoft Learn
登录
ssh USER@HOST
在使用 SSH 登录 Windows 时,容易遇到一个巨坑就是不知道远程 Windows 的用户名。由于远程 Windows 可能设置了 Microsoft 帐户的原因,远程 Windows 的用户名可能不是用户主目录的名字。你需要使用下面的命令来查看用户名:
$env:UserName
而密码则使用 Microsoft 帐户的密码。
上传公钥
管理员
Windows 上 OpenSSH 将管理员组(Administrators
)的公钥验证文件设置为 $env:ProgramData\ssh\administors_authorized_keys
。因此如果你登录的用户属于管理员组,那么将使用该文件(而不是 $env:USERPROFILE\.ssh\authorized_keys
)来验证你的身份。
因此我们需要把公钥添加到 $env:ProgramData\ssh\administors_authorized_keys
。
-
对于 Linux / macOS:
# 上传公钥文件 scp ~/.ssh/id_rsa.pub USER@HOST:/ProgramData/ssh/administrators_authorized_keys # 设置权限 ssh USER@HOST 'icacls "$env:ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant Administrators:F /grant SYSTEM:F'
将
USER
和HOST
分别改为你自己的用户名和主机名 -
对于 Windows:
# 存储公钥内容 $authorizedKey = Get-Content -Path $env:USERPROFILE\.ssh\id_rsa.pub # 上传公钥内容并设置权限 ssh USER@HOST "powershell Add-Content -Force -Path $env:ProgramData\ssh\administrators_authorized_keys -Value '''$authorizedKey'''; icacls.exe ""$env:ProgramData\ssh\administrators_authorized_keys"" /inheritance:r /grant ""Administrators:F"" /grant ""SYSTEM:F"""
这里没有使用
ssh-copy-id
命令,因为ssh-copy-id
内部会执行一些 *nix shell 命令,因此只能用于 *nix 机器。
标准用户
编辑 $env:ProgramData\ssh\sshd_config
,在文件最底部,注释掉这两行配置:
#Match Group administrators
# AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
此时所有用户的公钥验证文件都设置成了 $env:USERPROFILE\.ssh\authorized_keys
,此时再将公钥上传到远程 Windows 的 $env:USERPROFILE\.ssh\authorized_keys
文件:
-
对于 Linux / macOS:
# 上传公钥文件 scp ~/.ssh/id_rsa.pub USER@HOST:.ssh/authorized_keys # 设置权限 ssh USER@HOST 'icacls "$env:USERPROFILE\.ssh\authorized_keys" /inheritance:r /grant Everyone:F'
-
对于 Windows:
# 存储公钥内容 $authorizedKey = Get-Content -Path $env:USERPROFILE\.ssh\id_rsa.pub # 创建公钥目录及公钥文件 ssh USER@HOST "powershell New-Item -Force -ItemType Directory -Path $env:USERPROFILE\.ssh; Add-Content -Force -Path $env:USERPROFILE\.ssh\authorized_keys -Value '$authorizedKey'"
更改默认 Shell(可选)
通过 SSH 连接到 Windows 时默认登录的 Shell 是 CMD,可以在管理员终端中通过下面的命令将默认 Shell 改为 PowerShell 7(需要已安装 PowerShell 7):
# 添加默认 Shell 配置
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Program Files\PowerShell\7\pwsh.exe" -PropertyType String -Force
# 删除默认 Shell 配置
Remove-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH"
参考:
- Configuring the default shell for OpenSSH in Windows | Microsoft Learn
- 通过 SSH 进行 PowerShell 远程处理 - PowerShell | Microsoft Learn
Troubleshooting
无法登录:No auth methods could be used
有一次为了偷懒,没有上传公钥,想直接用密码登录 Windows。结果提示:
ssh: Connection to USER@HOST:22 exited: No auth methods could be used.
最后发现无法登录的原因是没有启用密码登录的选项。
解决方法:编辑 SSH 配置文件 $env:ProgramData\ssh\sshd_config
,找到 PasswordAuthentication
项,将选项改为 yes
:
PasswordAuthentication yes
然后重启 SSH 服务器。在终端(管理员)下运行:
Restart-Service sshd
然后再次尝试连接。
Operation timed out
在进行 SSH 连接时遇到如下错误:
ssh: connect to host 172.18.160.67 port 22: Operation timed out
解决方法:检查网络设置,确保当前网络配置文件类型为 专用网络
。因为防火墙默认只允许专用网络下的 SSH 入站流量。