如何在 Windows Server 上設置 OpenSSH [完整指南]

安全外殼(SSH)協議和OpenSSH項目在Linux上已經存在了數十年。但是,直到最近,Windows世界才開始接受OpenSSH。因此,Windows Server通常不會預先構建和就緒,需要進行一些設置。

在本教程中,您將學習如何像在Linux上一樣輕鬆地SSH到Windows Server。您將學習如何在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服務器。但是,Microsoft已經釋放了一個開源版本的OpenSSH供Windows使用。通過這個版本,現在可以在Windows機器上設置SSH服務器。

要開始,您首先需要下載OpenSSH。請按照以下步驟操作:

  1. 使用遠程桌面(RDP)或您喜歡的桌面管理器客戶端連接到Windows Server上的桌面。

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 Server 服務 (sshd) 和 OpenSSH Authentication Agent 服務 (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 Server。對於使用第三方防火牆的服務器,請參閱防火牆文檔,了解如何允許端口 22。

安裝OpenSSH並不會自動創建防火牆例外規則以允許SSH流量。因此,您的下一個任務是手動創建防火牆規則。

使用PowerShell和New-NetFirewallRule指令碼是創建新的Windows防火牆規則的最簡單方法之一。下面的命令創建一個名為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 Server 上打開提升權限的 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 服務器。

準備 administrators_authorized_keys 文件

公開金鑰必須放在伺服器上。但放在哪裡呢?對於在 Windows 上的 OpenSSH,SSH 伺服器從 C:\ProgramData\ssh\administrators_authorized_keys 檔案中讀取公開金鑰。但這個檔案默認不存在。您必須先創建一個。

請按以下步驟創建 administrators_authorized_keys 檔案,並設置其正確的 存取控制清單(ACL)

在 Windows 伺服器上:

1. 打開提升權限的 Windows PowerShell 控制台,如果還沒有的話。

2. 複製下面的命令,並在 PowerShell 中執行。此命令使用 New-Item 指令創建 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服務要求僅有管理員群組和SYSTEM帳戶才能訪問administrators_authorized_keys文件。將ssh_host_dsa_key的ACL複製到administrators_authorized_keys是有意義的,因為ACL已經設置。

4. 現在打開Windows Explorer。

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密鑰指定文件名。 要這樣做,在PowerShell控制台中的Windows Server上:

執行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 Server時:

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/