如何在Windows Server上安装OpenSSH [完整指南]

安全外壳(SSH)协议和OpenSSH项目在Linux上已经存在了几十年。但是直到最近,Windows世界才开始接受OpenSSH。因此,Windows服务器通常不会预先构建和准备就绪,需要进行一些设置。

在本教程中,您将学习如何像在Linux上那样轻松地通过SSH连接到Windows服务器。您将学习如何在Windows上安装(或更新)OpenSSH,添加适当的防火墙规则,并配置基于公钥、密码和证书的身份验证。

先决条件

为了有效地按照本文中的示例和演示进行操作,您需要满足以下要求。

  • A Windows Server machine – This article will use Windows Server 2019 Datacenter. The server this tutorial will use will have a user account called june and will connect to the server at the IP address of 40.117.77.227 with a hostname of ataWindows.
  • A local computer with PowerShell 7.1 installed. PowerShell 7.1 is available in Windows, Linux, and macOS. The examples in this article use PowerShell 7.1 in Windows 10.

下载OpenSSH

与Linux服务器不同,Windows服务器没有预装SSH服务器。但是微软已经发布了一个适用于Windows的开源端口OpenSSH。通过此版本,您现在可以在Windows机器上设置SSH服务器。

首先,您需要下载OpenSSH。请按照以下步骤操作:

  1. 使用远程桌面(RDP)或您首选的桌面管理器客户端连接到Windows服务器的桌面。

2. 在您的Windows Server桌面上,打开一个提升的Windows PowerShell控制台。

3. 接下来,复制下面的代码,粘贴到PowerShell窗口中,然后按Enter键。此脚本将下载最新的OpenSSH发布版,截至本文撰写时,版本为v8.1.0.0p1-Beta到当前工作目录。

如果您喜欢保存用于下载OpenSSH的PowerShell代码,您也可以打开诸如Windows PowerShell ISE或Visual Studio Code之类的代码编辑器,并将其保存在其中。

## 将网络连接协议设置为TLS 1.2
## 定义OpenSSH最新发布版的URL
 $url = 'https://github.com/PowerShell/Win32-OpenSSH/releases/latest/'
## 创建一个Web请求以检索最新的发布版下载链接
 $request = [System.Net.WebRequest]::Create($url)
 $request.AllowAutoRedirect=$false
 $response=$request.GetResponse()
 $source = $([String]$response.GetResponseHeader("Location")).Replace('tag','download') + '/OpenSSH-Win64.zip'
## 将最新的Windows OpenSSH包下载到当前工作目录
 $webClient = [System.Net.WebClient]::new()
 $webClient.DownloadFile($source, (Get-Location).Path + '\OpenSSH-Win64.zip')

4. OpenSSH-Win64.zip文件现在应该位于您的当前工作目录中。通过运行下面的命令验证这一点。

Get-ChildItem *.zip

如下所示,OpenSSH-Win64.zip文件存在于该目录中。

Checking if the OpenSSH zip file exists

安装OpenSSH

在您下载了OpenSSH-Win64.zip之后,下一步是在服务器上安装OpenSSH。如果您期望有安装向导,则没有。

  1. 在同一个 PowerShell 会话中,复制下面的代码并在 PowerShell 中运行。此代码将提取 OpenSSH-Win64.zip 文件的内容到 C:\Program Files\OpenSSH
# 将 ZIP 文件提取到临时位置
 Expand-Archive -Path .\OpenSSH-Win64.zip -DestinationPath ($env:temp) -Force
# 将提取的 ZIP 文件内容从临时位置移动到 C:\Program Files\OpenSSH\
 Move-Item "$($env:temp)\OpenSSH-Win64" -Destination "C:\Program Files\OpenSSH\" -Force
# 在 C:\Program Files\OpenSSH\ 中取消文件的阻止
 Get-ChildItem -Path "C:\Program Files\OpenSSH\" | Unblock-File

2. 在提取 ZIP 文件后,在 PowerShell 中运行以下命令执行脚本 C:\Program Files\OpenSSH\install-sshd.ps1。 此脚本安装 OpenSSH SSH 服务器服务(sshd)和 OpenSSH 认证代理服务(sshd-agent)。

& 'C:\Program Files\OpenSSH\install-sshd.ps1'

您可以在下面看到预期的结果。

Installing OpenSSH

为确保 SSH 服务器自动启动,请在 PowerShell 中运行以下命令。

## 将 sshd 服务的启动类型从手动更改为自动。
 Set-Service sshd -StartupType Automatic
## 启动 sshd 服务。
 Start-Service sshd

添加允许 SSH 流量的 Windows 防火墙规则

此过程仅适用于使用 Windows 防火墙的 Windows 服务器。对于使用第三方防火墙的服务器,请参考防火墙文档以允许端口 22。

安装OpenSSH不会自动创建防火墙例外规则以允许SSH流量。因此,您的下一个任务是手动创建防火墙规则。

创建新的Windows防火墙规则的最简单方法之一是使用PowerShell和New-NetFirewallRule cmdlet。下面的命令创建一个名为Allow SSH的防火墙规则,允许所有目标端口22的入站TCP流量。

复制下面的命令并在PowerShell中运行。

New-NetFirewallRule -Name sshd -DisplayName 'Allow SSH' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22

下面的截图显示创建防火墙规则后PowerShell中的预期输出。

Creating a Windows Firewall Rule to allow Port 22

使用密码认证连接SSH

到目前为止,您已在Windows上安装了OpenSSH并执行了初始服务器配置。下一步是测试通过SSH是否实际可行。

为了测试您新配置的SSH服务器,现在让我们在本地计算机上运行ssh命令。

本节中的相同步骤也适用于连接到Linux SSH服务器。

1. 这次从本地计算机打开PowerShell。

2. 接下来,运行以下命令以启动SSH登录过程。确保更改您的Windows服务器的用户名和远程主机。

ssh june@40.117.77.227

3. 由于你是第一次连接到服务器,你会看到一个提示,显示无法验证主机的真实性。这个消息意味着你的计算机尚未识别远程主机。输入yes,然后按 Enter 继续。

4. 当提示输入密码时,请输入你的帐户密码,然后按 Enter 键。

Connecting via SSH using Password Authentication

5. 登录后,如下面的屏幕截图所示,你将进入远程主机的命令提示符。假设你想确认自己已经在远程主机上的会话中。要执行此操作,请输入 hostname,然后按 Enter 键。该命令应返回远程计算机的名称。

Getting the hostname of the SSH server

将 OpenSSH 的默认 Shell 更改为 PowerShell

当你首次登录到 Windows SSH 服务器时,你会注意到默认的 shell 或命令解释器是 CMD。将 CMD 作为默认的 SSH shell 是可以的,但如果你希望使用 PowerShell 作为默认的 shell,可以按照以下步骤操作。

要将默认的 OpenSSH shell 从 CMD 更改为 PowerShell:

首先,在你的 Windows 服务器上打开一个提升的 PowerShell 窗口,如果你还没有打开的话。

接下来,在注册表键HKLM:\SOFTWARE\OpenSSH中创建一个名为DefaultShell的新的注册表字符串值。将DefaultShell 字符串数据设置为 Windows PowerShell 路径C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

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

下面的屏幕截图显示了命令的预期结果。

Changing the default OpenSSH shell

配置公钥认证

在之前的部分中,您使用用户名和密码连接。这样可以运作,但与SSH服务器进行身份验证的更安全的方式是使用密钥对

简而言之,密钥对包括两个称为公钥私钥的密钥,这构成了一组安全凭据,用于证明您的身份。

公钥存储在服务器上,而私钥则留在本地计算机上。您必须像对待密码一样处理私钥。如果私钥泄露,任何人都可以使用它来访问您的SSH服务器。

准备管理员_authorized_keys文件

公钥必须在服务器上。但在哪里呢?对于在Windows上的OpenSSH,SSH服务器会从C:\ProgramData\ssh\administrators_authorized_keys文件中读取公钥。但默认情况下,该文件不存在。您必须首先创建一个。

请按照以下步骤创建administrators_authorized_keys文件并设置其正确的访问控制列表(ACL)

在Windows服务器上:

1. 如果尚未,请打开提升权限的Windows PowerShell控制台。

2. 复制下面的命令并在PowerShell中运行。此命令使用New-Item cmdlet 创建administrators_authorized_keys文件。

New-Item -Type File -Path C:\ProgramData\ssh\administrators_authorized_keys

您应该看到类似于下面截图的结果。

Creating the administrators_authorized_keys file

3. 接下来,获取当前分配给ssh_host_dsa_key文件的ACL,并将该ACL复制到administrators_authorized_keys文件。要执行此操作,请运行以下命令。

get-acl C:\ProgramData\ssh\ssh_host_dsa_key | set-acl C:\ProgramData\ssh\administrators_authorized_keys

OpenSSH服务要求只有Administrators组和SYSTEM账户才能访问administrators_authorized_keys文件。将ssh_host_dsa_key的ACL复制到administrators_authorized_keys是有意义的,因为ACL已经设置好了。

4. 现在打开Windows资源管理器。

5. 导航到C:\ProgramData\ssh\文件夹。

6. 右键单击administrators_authorized_keys文件,然后点击属性

7. 在属性页面上,点击安全选项卡,然后点击高级

Opening advanced security settings

8. 确认权限是否如下图所示。

Viewing advanced security permission

生成新的SSH密钥对

要生成新的SSH密钥对,请使用ssh-keygen命令,该命令是Windows 10(及以上版本)和大多数Linux操作系统内置的OpenSSH客户端工具的一部分。

本节中显示的示例适用于Windows和Linux计算机。

在本地计算机的PowerShell控制台中:

1. 通过运行以下命令导航到您的主文件夹的.ssh目录。

cd ~/.ssh

2. 接下来,输入命令 ssh-keygen 并按 Enter 键。当要求输入保存生成的密钥的文件位置时,请保持默认位置并按 Enter 键。这样做可以使您的 SSH 客户端在自动进行身份验证时找到您的 SSH 密钥。

在 Windows 中,默认密钥文件位于 C:\Users\<username>\.ssh\id_rsa。

3. 在下一个提示处,将密码留空。在这一点上,您不必为测试使用密码。

向私钥添加密码会显著提高其安全性。密码充当对私钥的第二因素身份验证 (2FA)。

您会注意到该命令创建了两个文件;id_rsa(私钥)和id_rsa.pub(公钥)。

Generating a new SSH key pair on the local computer

将公钥部署到 Windows SSH 服务器

现在您已生成私钥-公钥对,下一步是将公钥复制到 SSH 服务器上的C:\ProgramData\ssh\administrators_authorized_keys 文件。

在本地计算机上,在 PowerShell 控制台中:

1. 复制下面的代码并在 PowerShell 中运行。确保首先更改用户名和 IP 地址。您可以参考每个命令上方的注释,了解每个命令的作用。

# 读取公钥
 $public_key = Get-Content ~/.ssh/id_rsa.pub
# 使用 ssh 将公钥附加到服务器上的 administrators_authorized_keys
 ssh june@40.177.77.227 "'$($public_key)' | Out-File C:\ProgramData\ssh\administrators_authorized_keys -Encoding UTF8 -Append"

2. 在提示时输入您的密码,然后ssh将继续复制公钥。您将看到类似的结果,如下所示。

Deploying the public key to the Windows SSH server

使用公钥身份验证连接SSH

现在您已将公钥复制到SSH服务器上,您就不再需要使用密码进行身份验证了。正如您下面所看到的,ssh没有提示输入密码。

Connecting with SSH using Public Key Authentication

配置证书身份验证

与公钥身份验证类似,证书身份验证是无需密码或受口令保护的。要启用证书登录,请按照生成密钥对并将公钥部署到SSH服务器的相同步骤进行操作。

您无需将公钥映射到SSH服务器上的authorized_keys或administrators_authorized_keys文件中。相反,公钥是使用证书授权机构(CA)密钥签名的。

创建证书授权机构(CA)密钥

生成用于签名的CA密钥与您在本文中之前生成的用户密钥对类似。只是这一次,您需要为新的CA密钥指定一个文件名。要这样做,在您的Windows服务器上打开PowerShell控制台:

执行以下命令ssh-keygen。此命令将在C:\ProgramData\ssh\ca_userkeys中创建CA密钥,但可以自由选择不同的文件名。使用不同的文件名不会影响CA密钥的功能。

当要求输入密码时,请将密码留空并按Enter键。

ssh-keygen -f C:\ProgramData\ssh\ca_userkeys

您可以看到下面的命令创建了两个文件。ca_userkeys是私钥,ca_userkeys.pub是公钥。

Creating the Certificate Authority (CA) Key on a Windows SSH server

现在您已经生成了CA密钥,请告诉SSH服务器信任CA以及在哪里找到CA密钥。为此,请在服务器的C:\ProgramData\ssh\sshd_config文件中添加新行TrustedUserCAKeys path/to/ca_userkeys.pub

运行以下命令将配置项添加到sshd_config文件中。

# 如果SSH服务器是Windows
 echo TrustedUserCAKeys C:\ProgramData\ssh\ca_userkeys.pub>> C:\ProgramData\ssh\sshd_config

签署用户的公钥

此时,您已经生成了CA密钥并配置了SSH服务器信任CA公钥文件。现在剩下的就是签署您的用户公钥。

在您的本地计算机上,在PowerShell控制台中:

1. 使用SCP命令将id_rsa.pub文件复制到SSH服务器上的主目录。确保更改用户名和IP地址为正确的值。

scp ((Resolve-Path ~/.ssh/id_rsa.pub).Path) june@40.117.77.227:id_rsa.pub

2. 使用ssh登录到您的Windows服务器。一旦登录成功,运行ssh-keygen以签署用户的公钥。您会注意到下面的命令使用了几个参数。让我们逐一解释它们。

  • -s C:\ProgramData\ssh\ca_userkeys – 指定CA密钥的位置以签署公钥。在这个示例中,CA密钥是您生成的密钥。
  • -I id_username – 指定要分配给已签署用户公钥的ID。将id_username的值更改为您想要的任何名称。
  • -V +4w – 此参数指定已签名密钥的有效期。在这个示例中,+4w表示已签名用户密钥将在四周内有效。您可以将此值更改为您偏好的有效期。
  • -n username – 这是将拥有已签名公钥的用户名。
  • <path to id_rsa.pub> – 这是要签署的用户公钥的位置(Windows)。
ssh-keygen -s C:\ProgramData\ssh\ca_userkeys -I id_username -V +4w -n username ~/id_rsa.pub

在您的SSH会话中运行该命令后,您应该会得到类似下面显示的输出。如您所见,该命令生成了一个名为id_rsa-cert.pub的新文件,这是已签名的用户证书。

Signing the User Key

3. 现在,返回到您的本地计算机PowerShell会话,并将id_rsa-cert.pub文件从服务器复制到您的本地计算机。在运行该命令之前,请先更改用户名和IP地址为正确的值。

scp june@40.117.77.227:id_rsa-cert.pub ((Resolve-Path ~/.ssh/).Path)

复制完成后,您会在您的主文件夹中找到已签名的用户证书,如下所示。

Finding the SSH user certificate

使用证书认证连接SSH

您已配置了证书认证,现在您已经拥有了用户证书。您现在应该测试是否可以使用证书认证连接SSH服务器。

使用证书连接SSH的命令与使用密码或公钥相同。但是,如果您之前启用了公钥认证,请先禁用它。否则,SSH将继续使用您的密钥对而不是您的证书。

要禁用密钥对,请从administrators_authorized_keys文件中删除您的公钥。请按照以下步骤操作。

请注意,后续命令将清空整个administrators_authorized_keys文件,从而有效地删除所有映射的公钥。如果您不想清除所有映射的公钥,请使用文本编辑器手动从每个文件中删除所选的公钥。

在SSH连接到Windows服务器时:

1. 在PowerShell中运行以下代码以清空administrators_authorized_keys文件。

# 清空administrators_authorized_keys文件
 $NULL > C:\ProgramData\ssh\administrators_authorized_keys
# 确认administrators_authorized_keys文件已清空
 Get-Content C:\ProgramData\ssh\administrators_authorized_keys

2. 此时,authorized_keys和administrators_authorized_keys文件都为空,如下面的截图所示。

Emptying the administrators_authorized_keys

3. 输入exit并按Enter断开SSH会话。您将返回到PowerShell会话。

4. 删除公钥后,您的下一次SSH登录尝试将使用证书认证。登录体验将与使用公钥认证相同。

Connecting with SSH using Certificate Authentication

结论

您现在已经从头开始设置了一个OpenSSH Windows服务器,一直到探索和设置各种认证方式。现在您可以像在Linux上一样连接到您的Windows服务器了!

Source:
https://adamtheautomator.com/openssh-windows/