適用于 Windows 的 OpenSSH 中的金鑰型驗證

適用于 Windows Server 2022、Windows Server 2019、Windows 10(組建 1809 和更新版本)

Windows 環境中大部分的驗證都是使用使用者名稱-密碼組來完成,這適用于共用通用網域的系統。 跨網域工作時,例如在內部部署與雲端裝載系統之間,它很容易遭受暴力密碼破解入侵。

相較之下,Linux 環境通常會使用公開金鑰/私密金鑰組來驅動不需要使用可猜測密碼的驗證。 OpenSSH 包含可協助支援金鑰型驗證的工具,特別是:

  • ssh-keygen,用來產生安全金鑰
  • ssh-agentssh-add,用來安全地儲存私密金鑰
  • scpsftp,在初始使用伺服器期間安全地複製公開金鑰檔案

本檔概述如何在 Windows 上使用這些工具,以搭配 SSH 開始使用金鑰型驗證。 如果您不熟悉 SSH 金鑰管理,強烈建議您檢閱 名為「使用安全殼層進行互動式和自動化存取管理的安全性」的 NIST 檔 IR 7966

關於金鑰組

金鑰組指的是特定驗證通訊協定所使用的公開和私密金鑰檔案。

SSH 公開金鑰驗證會使用非對稱密碼編譯演算法來產生兩個金鑰檔案 ,一個是「私人」,另一個是「公用」。 私密金鑰檔案相當於密碼,且在所有情況下都應受到保護。 如果有人取得您的私密金鑰,他們可以以您身分登入您有權存取的任何 SSH 伺服器。 公開金鑰是放在 SSH 伺服器上的金鑰,而且可以在不危及私密金鑰的情況下共用。

金鑰型驗證可讓 SSH 伺服器和用戶端比較針對私密金鑰提供之使用者名稱的公開金鑰。 如果伺服器端公開金鑰無法針對用戶端私密金鑰進行驗證,驗證就會失敗。

當產生金鑰組時,可以透過金鑰組來實作多重要素驗證,方法是輸入複雜密碼(請參閱 下面的使用者金鑰產生 )。 在驗證期間,系統會提示使用者輸入複雜密碼。 複雜密碼會與 SSH 用戶端上的私密金鑰是否存在一起使用,以驗證使用者。

重要

透過金鑰型驗證開啟的遠端會話沒有相關聯的使用者認證,因此無法以使用者身分進行輸出驗證,這是根據設計。

主機金鑰產生

公開金鑰具有特定的 ACL 需求,在 Windows 上等同於只允許系統管理員和系統的存取權。 第一次使用 sshd 時,將會自動產生主機的金鑰組。

重要

您必須先安裝 OpenSSH Server。 請參閱 開始使用 OpenSSH

根據預設,sshd 服務會設定為手動啟動。 若要在每次重新開機伺服器時啟動它,請從伺服器上提升許可權的 PowerShell 提示字元執行下列命令:

# Set the sshd service to be started automatically
Get-Service -Name sshd | Set-Service -StartupType Automatic

# Now start the sshd service
Start-Service sshd

由於沒有任何使用者與 sshd 服務相關聯,因此主機金鑰會儲存在 C:\ProgramData\ssh 底下。

使用者金鑰產生

若要使用金鑰型驗證,您必須先為用戶端產生公開/私密金鑰組。 ssh-keygen.exe 可用來產生金鑰檔案,並指定 DSA、RSA、ECDSA 或 Ed25519 演算法。 如果未指定任何演算法,則會使用 RSA。 應使用強演算法和金鑰長度,例如本範例中的 Ed25519。

若要使用 Ed25519 演算法產生金鑰檔案,請在用戶端上從 PowerShell 或 Cmd 提示字元執行下列命令:

ssh-keygen -t ed25519

命令的輸出應該會顯示下列輸出(其中 「username」 會由您的使用者名稱取代):

Generating public/private ed25519 key pair.
Enter file in which to save the key (C:\Users\username/.ssh/id_ed25519):

您可以按 Enter 以接受預設值,或指定要產生金鑰的路徑和/或檔案名。 此時,系統會提示您使用複雜密碼來加密您的私密金鑰檔案。 複雜密碼可以是空的,但不建議這麼做。 複雜密碼可與金鑰檔案搭配使用,以提供雙因素驗證。 在此範例中,我們將複雜密碼保留空白。

Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\username/.ssh/id_ed25519.
Your public key has been saved in C:\Users\username/.ssh/id_ed25519.pub.
The key fingerprint is:
SHA256:OIzc1yE7joL2Bzy8!gS0j8eGK7bYaH1FmF3sDuMeSj8 username@LOCAL-HOSTNAME

The key's randomart image is:
+--[ED25519 256]--+
|        .        |
|         o       |
|    . + + .      |
|   o B * = .     |
|   o= B S .      |
|   .=B O o       |
|  + =+% o        |
| *oo.O.E         |
|+.o+=o. .        |
+----[SHA256]-----+

現在,您在指定的位置中有公用/私人 ed25519 金鑰組。 .pub 檔案是公開金鑰,沒有副檔名的檔案是私密金鑰:

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----         6/3/2021   2:55 PM            464 ed25519
-a----         6/3/2021   2:55 PM            103 ed25519.pub

請記住,私密金鑰檔案相當於密碼,應該與保護密碼的方式一樣加以保護。 使用 ssh-agent 安全地將私密金鑰儲存在與 Windows 帳戶相關聯的 Windows 安全性內容中。 若要在每次重新開機電腦時啟動 ssh-agent 服務,並使用 ssh-add 來儲存私密金鑰,請從伺服器上提升許可權的 PowerShell 提示字元執行下列命令:

# By default the ssh-agent service is disabled. Configure it to start automatically.
# Make sure you're running as an Administrator.
Get-Service ssh-agent | Set-Service -StartupType Automatic

# Start the service
Start-Service ssh-agent

# This should return a status of Running
Get-Service ssh-agent

# Now load your key files into ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519

將金鑰新增至用戶端上的 ssh-agent 之後,ssh-agent 會自動擷取本機私密金鑰,並將其傳遞至 SSH 用戶端。

重要

強烈建議您將私密金鑰備份至安全的位置,然後在將它新增至 ssh-agent 之後,從本機系統將它刪除。 私密金鑰無法從提供強式演算法的代理程式擷取,例如此範例中的 Ed25519。 如果您失去私密金鑰的存取權,您必須建立新的金鑰組,並在您與之互動的所有系統上更新公開金鑰。

部署公開金鑰

若要使用上面建立的使用者金鑰,公開金鑰的內容 ( \.ssh\id_ed25519.pub ) 必須放在伺服器上,才能放入文字檔中。 檔案的名稱和位置取決於使用者帳戶是本機系統管理員群組的成員還是標準使用者帳戶。 下列各節涵蓋標準和系統管理使用者。

標準使用者

公開金鑰的內容 ( \.ssh\id_ed25519.pub ) 必須放在伺服器上,以 C:\Users\username\.ssh\ 呼叫 authorized_keys 的文字檔。 您可以使用 OpenSSH scp 安全檔案傳輸公用程式,或使用 PowerShell 將金鑰寫入檔案,來複製公開金鑰。

下列範例會將公開金鑰複製到伺服器(其中 「username」 會由您的使用者名稱取代)。 您一開始必須針對伺服器的使用者帳戶使用密碼。

# Get the public key file generated previously on your client
$authorizedKey = Get-Content -Path $env:USERPROFILE\.ssh\id_ed25519.pub

# Generate the PowerShell to be run remote that will copy the public key file generated previously on your client to the authorized_keys file on your server
$remotePowershell = "powershell New-Item -Force -ItemType Directory -Path $env:USERPROFILE\.ssh; Add-Content -Force -Path $env:USERPROFILE\.ssh\authorized_keys -Value '$authorizedKey'"

# Connect to your server and run the PowerShell using the $remotePowerShell variable
ssh username@domain1@contoso.com $remotePowershell

管理員使用者

公開金鑰的內容 ( \.ssh\id_ed25519.pub ) 必須放在伺服器上,放入 C:\ProgramData\ssh\ 中稱為 administrators_authorized_keys 文字檔。 您可以使用 OpenSSH scp 安全檔案傳輸公用程式,或使用 PowerShell 將金鑰寫入檔案,來複製公開金鑰。 此檔案上的 ACL 必須設定為只允許存取系統管理員和系統。

下列範例會將公開金鑰複製到伺服器,並設定 ACL(其中 「username」 會取代為您的使用者名稱)。 您一開始必須針對伺服器的使用者帳戶使用密碼。

注意

此範例示範建立 administrators_authorized_keys 檔案的步驟。 這只適用于系統管理員帳戶,而且必須是使用者,而不是使用者設定檔位置內的每個使用者檔案。

# Get the public key file generated previously on your client
$authorizedKey = Get-Content -Path $env:USERPROFILE\.ssh\id_ed25519.pub

# Generate the PowerShell to be run remote that will copy the public key file generated previously on your client to the authorized_keys file on your server
$remotePowershell = "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"""

# Connect to your server and run the PowerShell using the $remotePowerShell variable
ssh username@domain1@contoso.com $remotePowershell

這些步驟會完成在 Windows 上使用金鑰型驗證與 OpenSSH 所需的設定。 執行範例 PowerShell 命令之後,使用者就可以從具有私密金鑰的任何用戶端連線到 sshd 主機。