Skip to content

Instantly share code, notes, and snippets.

@wklchris
Last active April 25, 2024 03:21
Show Gist options
  • Save wklchris/d875e7056d5536ab520a7921f85a2a7c to your computer and use it in GitHub Desktop.
Save wklchris/d875e7056d5536ab520a7921f85a2a7c to your computer and use it in GitHub Desktop.
Windows 免密码 SSH 连接指南

Windows 免密码 SSH 连接指南

以从 Windows 设备(本地机)通过 SSH 连接到另一台 Windows 设备(远程机)为例。毕竟 Windows 是最难配置的,如果有一边是 Linux 设备会简单很多。

  • 需要 Windows 10 或者更高的系统版本,以确认 OpenSSH 组件的安装。
  • 不需要安装第三方 SSH 软件。

目录:


本地机 OpenSSH 配置

在本地机上,以管理员身份启动 Powershell,并按装 OpenSSH.Client

Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

远程机 OpenSSH 配置

在远程机上,同样以管理员身份启动 Powershell。这次则需要安装 OpenSSH.Server

Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

更改注册表键值,将 SSH 登录后的默认 shell 改完 Powershell(默认是 CMD):

New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "$(Get-Command powershell | % Source)" -PropertyType String -Force

上述的 Get-Command powershell | % Source 实际上是返回 Windows 的默认 Powershell 路径。

最后,启动 sshd 服务,并设置为自动运行:

Start-Service sshd
Set-Service -Name sshd -StartupType Automatic

如果要 SSH 到远程机 Admin 账户……

如果只需要 SSH 到远程机普通账户,可以跳过本节。

警告:下述方法是一个不规范的懒人操作,它会使所有 authorized_keys 受信用户都能直接 SSH 到远程机的 Admin 账户,因此存在显著的风险

正确的做法是编辑 administrators_authorized_keys 文件,这可能还涉及到该文件的权限管理:

icacls.exe "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"

请自行查询相关的内容。

如果你要从本地机 SSH 到远程机的 Admin 账户,你还需要在远程机上编辑 C:\ProgramData\ssh\sshd_config 文件。请在远程机上,以管理员模式启动 Powershell,并执行:

notepad C:\ProgramData\ssh\sshd_config

在弹出的记事本编辑窗口中,找到最下方的这两行并注释掉:

#Match Group administrators
#       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

如上所示,在这两行的前方各插入一个 # 来注释。这样 sshd 就不会查询该目录下的 administrators_authorized_keys 文件,而是查询默认的 ~/.ssh/authorized_keys 文件。

在更改完成后,需要重启 SSH Server 服务。你可以运行 services.msc 并找到 OpenSSH SSH Server,右键选择重新启动。

生成设备密钥

本地机上需要配置设备密钥,以方便进行 SSH 连接。

  1. 打开本地机 ~\.ssh 文件夹(Invoke-Item ~/.ssh),并检查其中的文件。

    如果已经存在 id_rsa(私钥)以及 id_rsa.pub(公钥)文件,则说明已生成过 RSA 密钥,可以跳过本节,无须再生成一次。如果看到 id_ed25519 (或其他类似文件名)则表示是用 ed25519 生成过密钥,也无须再生成一次。

  2. 如果没有已生成的密钥,那么需要生成一个。从 Powershell 运行以下命令来默认生成一个 RSA 密钥:

    ssh-keygen

    如果要生成 ed25519 密钥,则使用 ssh-keygen -t ed25519 命令。

  3. 命令行提示你指定密钥文件保存位置,默认即可。

  4. 它会提示你为密钥输入密码,建议指定一个密码。

  5. 完成生成后,以 RSA 为例,你会在 ~\.ssh 文件夹中看到 id_rsa(私钥)以及 id_rsa.pub(公钥)两个文件。

将私钥添加到本地机 ssh-agent

要在 SSH 连接时免除输入密钥的密码,需要让本地机的 ssh-agent 服务托管该密钥。

  1. 在本地机上以管理员身份运行 Powershell,并启动 ssh-agent 服务:

    Get-Service ssh-agent | Set-Service -StartupType Manual
    Start-Service ssh-agent
  2. 添加密钥(私钥):

    cd ~/.ssh
    ssh-add id_rsa

    如果使用的是 ed25519 或其他方式生成的密钥,请相应地更改上述 id_rsa 私钥名称。

将公钥添加到远程机的受信列表

要在 SSH 连接远程机时免除输入远程机账户的密码,需要将本地的公钥(而不是私钥)文本内容添加到远程机的 authorized_keys 文件中。

  1. 在本地机上打开 Powershell,复制本地的公钥(以 RSA 密钥为例)到剪贴板:

    cat ~/.ssh/id_rsa.pub | clip
  2. 使用 SSH 命令登录到远程机的 USER 用户:

    ssh USER@HOST

    以局域网为例:ssh wklchris@192.168.x.x。请注意,如果要使用局域网 IP 地址来访问远程机,请在路由器中为远程机分配一个固定的局域网 IP。如果你不知道远程机的局域网 IP,可以在远程机上,使用下述命令查询:

    (Get-NetIPAddress -InterfaceAlias WLAN -AddressFamily IPv4).IPAddress
  3. 按 SSH 提示,输入远程机中 USER 账户的登录密码以建立连接。

  4. 现在你已经成功连接到远程机的 Powershell 了。接下来需要把在步骤 1 中复制的本地机公钥添加到远程机的受信文件中。我们可以创建一个变量来保存刚才的复制文本(请将单引号内的 PASTE 替换为你复制的公钥文本):

    $key='PASTE'
  5. 将它追加到远程机的 authorized_keys 文件末尾(已另起一行):

    Add-Content ~/.ssh/authorized_keys "`n$key"
  6. 你可以打印该文件内容到 Powershell 来确认已添加:

    cat ~/.ssh/authorized_keys
  7. 输入 exit 并回车,以退出远程机的 SSH 连接。此时你已经返回本地机的 Powershell 了。

最终测试

至此,所有的配置均已完成了。但远程机仍可能需要对 SSH Server 服务进行一次重启。

  1. 在远程机上,运行 services.msc 并找到 OpenSSH SSH Server,右键选择重新启动。

  2. 在本地机上,打开 Powershell,并尝试用 ssh 命令连接远程机。

  3. 此时, SSH 应该能无须输入任何密码地连接到远程机了。

  4. 如一切测试无问题,在本地机上将 ssh-agent 服务设置为自动,以在下次启动电脑后仍能免密连接:

    Get-service ssh-agent | Set-service -StartupType Automatic
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment