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'
    

    USERHOST 分别改为你自己的用户名和主机名

  • 对于 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 机器。

    参考:OpenSSH for Windows 中基于密钥的身份验证 | Microsoft Learn

标准用户

编辑 $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'"
    

    参考:多台 WIN 10 之间的 SSH 免密登录 | 知乎

更改默认 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"

参考:

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 入站流量。

image

image

posted @ 2024-01-22 01:10  Undefined443  阅读(474)  评论(0编辑  收藏  举报