Featured image of post Windows 10/11 配置 OpenSSH Server:密钥登录与默认 shell

Windows 10/11 配置 OpenSSH Server:密钥登录与默认 shell

- 密钥登录更安全

前言

Windows 10/11 自带了 OpenSSH Server(以“可选功能”的形式提供),可以让你像在 Linux 系统上一样远程使用 shell。本文介绍如何安装和配置 OpenSSH Server、如何使用密钥登录,以及如何把默认终端从 cmd 改为 PowerShell。

下文中“服务器”指要被远程登录的那台 Windows 电脑,“客户端”指你用来发起 ssh 连接的电脑。所有 PowerShell 命令都需要以管理员身份运行。

安装 OpenSSH Server

  1. 以管理员身份打开 PowerShell。

  2. 查看 OpenSSH 相关组件的安装状态:

    1
    
    Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
    
  3. 安装 OpenSSH Server:

    1
    
    Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
    

    当然,你也可以通过图形界面安装:“设置” → “应用” → “可选功能” → “添加功能”(Win11 为“查看功能”),搜索并勾选“OpenSSH 服务器”即可。

  4. 启动 OpenSSH Server:

    1
    
    Start-Service sshd
    
  5. 设置 OpenSSH Server 开机自启:

    1
    
    Set-Service -Name sshd -StartupType 'Automatic'
    
  6. 检查 OpenSSH Server 是否已经启动:

    1
    
    Get-Service sshd
    
  7. 安装程序一般会自动创建名为 OpenSSH-Server-In-TCP 的防火墙入站规则(放行 TCP 22 端口),可以确认一下:

    1
    
    Get-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' | Select-Object Name, Enabled
    

    如果提示找不到该规则,手动创建:

    1
    
    New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
    

配置密钥登录

1. 生成密钥对

在客户端上生成密钥对,如果已经有密钥对可以跳过这一步。常用的密钥类型有 rsa、ecdsa、ed25519(dsa 已被新版 OpenSSH 默认禁用,不要再用),这里使用 ed25519:

1
ssh-keygen -t ed25519

生成的公钥默认是 ~/.ssh/id_ed25519.pub(Windows 上即 C:\Users\<用户名>\.ssh\id_ed25519.pub)。

2. 把公钥放到服务器上

特别注意!! 与 Linux 下的 OpenSSH Server 不同,Windows 版 OpenSSH 的 sshd_config 末尾默认有这样一段:

1
2
Match Group administrators
       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

也就是说,管理员组的用户不会读取自己目录下的 ~/.ssh/authorized_keys,而是统一读取 C:\ProgramData\ssh\administrators_authorized_keys。公钥放错地方,就会一直提示输入密码:

公钥应该放在哪里

根据你的情况二选一:

做法 A:注释掉 Match 段(我的做法)

用管理员权限的编辑器(例如以管理员身份运行的 VS Code 或记事本)打开 C:\ProgramData\ssh\sshd_config,把上面两行注释掉:

1
2
# Match Group administrators
#        AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

然后把客户端公钥的内容追加到服务器上的 C:\Users\<用户名>\.ssh\authorized_keys 文件中(没有 .ssh 目录就新建一个)。这样管理员和普通用户的行为就和 Linux 一致了。

做法 B:保持默认,使用 administrators_authorized_keys

把公钥内容追加到 C:\ProgramData\ssh\administrators_authorized_keys,然后在管理员 PowerShell 中修正它的权限(只允许 Administrators 和 SYSTEM 访问,否则 sshd 会拒绝读取):

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

3. 编辑 sshd_config

继续编辑 C:\ProgramData\ssh\sshd_config(修改需要管理员权限),确认以下配置:

1
2
3
4
# 启用密钥登录
PubkeyAuthentication yes
# 禁止密码登录,确保安全性(建议先确认密钥能登录再改)
PasswordAuthentication no

注意:sshd_config 只把以 # 开头的行当作注释,不要把注释写在配置项的同一行后面。

修改完成后保存并退出。

4. 重启 sshd 服务

在 PowerShell(管理员)中重启 sshd 服务,让配置生效:

1
Restart-Service sshd

设置默认 shell 为 PowerShell

Windows OpenSSH 默认的 shell 是 cmd。在 PowerShell(管理员)中运行以下命令,把默认 shell 改为 Windows PowerShell:

1
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force

修改对之后的新连接生效。想改回 cmd,删除这个注册表值即可:

1
Remove-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell

连接

没啥说的了吧,你肯定会了。在客户端上:

1
ssh <用户名>@<服务器 IP 或主机名>
  • 用户名是服务器上的本地账户名,不确定的话在服务器上运行 whoami 看一下(输出为 计算机名\用户名)。
  • 连不上时加 -v 查看详细过程:ssh -v <用户名>@<服务器>;服务器端的日志可以在“事件查看器” → “应用程序和服务日志” → “OpenSSH” → “Operational”中查看。

一切正常的话,大概是这样:

验证服务状态并登录

引用

由 Hugo 强力驱动