PowerShell Remoting(PSRemoting)解釋:最終指南

PowerShell 遠程操作(PSRemoting)是 PowerShell 中最常用的功能之一。為什麼呢?因為它非常實用!只需一個命令,您就可以無縫地連接到一個或數千台遠程計算機並執行命令。

在這個終極指南中,您將深入了解 PSRemoting。您將了解它是什麼,它是如何工作的,以及使 PSRemoting 正常運作的各種技術。本指南不會涵蓋如何使用 PSRemoting。您將在整個指南中看到許多參考我們的操作指南。

PSRemoting 的工作原理

簡單來說,PSRemoting 允許您像坐在計算機前一樣在遠程計算機上運行命令。PSRemoting 提供了一組功能,用於連接和驗證用戶,運行遠程命令並將該命令的任何輸出返回到本地計算機。

把 PSRemoting 想像成 telnet 或 SSH,甚至是 psexec。它只是一種在 PowerShell 中運行命令的方式。

PSRemoting 在很大程度上依賴於一個稱為會話的概念。會話是指在其中運行命令的遠程 shell。創建這些會話的過程在後台進行多個步驟。

當您啟動一個 PSRemoting 會話時,以下大致步驟將進行:

  • 客戶端嘗試連接到目標伺服器上的 WinRM 監聽器(有關 WinRM 監聽器的更多資訊請參見下文)。WinRM 監聽器是運行在目標伺服器上的一個小型網頁服務。WinRM 是微軟對稱網路管理 (WS-Management) 標準的實現。WS-Management 是一個開放標準,當時由許多大型科技公司(如 Dell、Intel 和 Sun Microsystems)共同創建。
  • 當客戶端通過 HTTP 或 HTTPS 協議連接到監聽器時,認證過程開始。每種認證方法的詳細資料將在後面介紹,但現在只需知道客戶端需要以某種方式將憑證傳遞給伺服器。
  • 客戶端連接並通過驗證後,PSRemoting 將建立一個會話。
  • 一旦 PSRemoting 建立了會話,它就開始運作。此時,客戶端可以開始向伺服器發送資訊,伺服器則返回任何必要的輸出,稱為序列化。此通訊通常是加密的。
Creating a PSSession with PSRemoting

WinRM 監聽器:可用於連接的監聽器

A client needs somewhere to connect to when coming in from over the network. The client needs to “talk” to something that’s “listening” on the other side; that “listening” is the role of the WinRM listener.

您可以使用以下 winrm 命令發現運行在任何 Windows 電腦上的所有 WinRm 監聽器。

winrm e winrm/config/listener
WinRm listeners

WinRm 監聽器具有一些重要的組件。它們包括:

  • A listening address – The listening address is the IP address that they bind to. This is the IP address that a client connects to.
  • 傳輸類型 – 每個WinRM監聽器都需要一種與客戶端通信的方式;它們通過使用HTTP或HTTPS進行傳輸來實現這一點。
  • 可選的憑證指紋 – 當WinRM監聽器使用HTTPS進行傳輸時,它必須知道要對客戶端進行身份驗證的私鑰是什麼;此私鑰可通過憑證指紋找到。

在可能的情況下,請使用HTTPS監聽器。設置HTTPS傳輸可以通過確保服務器的有效性以及對身份驗證和傳輸流量的加密,提高安全性。在發行憑證時,請盡量使用來自認證機構的可信憑證,而不是自簽名的憑證。

受信任的主機:驗證服務器

關於WinRM的PSRemoting身份驗證工作原理

如上所述,PSRemoting的首要步驟之一是身份驗證。身份驗證是PSRemoting中最複雜但也是最重要的部分之一。

當PSRemoting首次引入時,它只有一種身份驗證機制,即Windows遠程管理(WinRM),但現在,您還可以使用SSH進行身份驗證,這將在稍後介紹。

WinRM支持兩種不同類型的身份驗證;使用用戶名和密碼或憑證進行身份驗證的各種身份驗證方式的組合。

基本身份驗證

從最簡單但最不安全的身份驗證開始,基本身份驗證是內置於HTTP協議中的標準。基本身份驗證將使用者名稱和密碼的Base64編碼副本通過HTTP標頭從客戶端發送到監聽器。

由於基本身份驗證僅對使用者名稱和密碼進行編碼而不加密,對於在網絡上截取憑據非常簡單。

除非絕對必要,否則不要使用基本身份驗證。WinRM可以使用許多其他更安全的方法進行身份驗證!

Kerberos身份驗證

你的客戶端和服務器都在Active Directory環境中嗎?如果是,你已經在許多網絡服務中使用了Kerberos身份驗證

當WinRM客戶端嘗試通過Kerberos連接到WinRM監聽器時:

  • 服務器首先嘗試從域控制器獲取客戶端的會話密鑰或票據授權票據。
  • 域控制器查找客戶端和服務器,如果兩者都是有效且受信任的,則發出令牌。
  • 然後,服務器使用受信任的令牌驗證客戶端的連接,而不使用使用者名稱和密碼。

在Kerberos身份验证期间,域控制器在票据检索步骤中验证客户端和服务器,防止恶意用户冒充服务器。

Kerberos是一种成熟且安全的身份验证方法,在客户端和服务器都是Active Directory域的成员时,默认为身份验证类型。但是,它要求客户端和服务器加入同一个Active Directory林或在林之间建立信任关系。

Negotiate身份验证

WinRm也可以尝试使用Kerberos,如果不可用,它会回退并尝试使用一种名为NT Lan Manager(NTLM)的身份验证协议。

在使用NTLM时:

  • 服务器向客户端发送一个字符串。
  • 然后,客户端使用用户密码的哈希值对该字符串进行加密。
  • 然后,将加密后的字符串发送回服务器,服务器将用户名、原始字符串和加密字符串发送给域控制器。
  • 域控制器然后查找该用户的密码哈希值,并对字符串进行相同的加密过程以确保匹配。

NTLM對於驗證客戶端是很好的,但不像Kerberos一樣驗證服務器。這就打開了多種攻擊方式,攻擊者可以冒充服務器。

您可以通過使用服務器驗證證書並將其分配給HTTPS WinRM來提高NTLM的安全性。在此設置中,客戶端使用NTLM對域控制器進行驗證,而服務器則使用受信任的證書進行驗證。儘管此設置提供了客戶端和服務器驗證,但NLTM協議使用了一種較舊的加密算法,其密鑰大小已過時。

出於這些原因,只有將服務器添加到信任的主機列表或使用HTTPS侦听器時,NLTM才可用。

摘要驗證

在WinRM中,最不常見的身份驗證方法之一是摘要驗證。NTLM和摘要是類似的身份驗證方法。與NTLM一樣,摘要會生成一個使用用戶密碼的哈希加密的唯一字符串。然後,密碼不需要發送到服務器。

摘要使用MD5哈希算法來加密密碼。由於選擇了這種算法,摘要通常被視為過時且不應使用。MD5存在各種已知的漏洞,使其不適用於加密使用。

憑證安全支持提供程序(CredSSP)

雖然我們可以深入研究CredSSP的詳情,但這並不必要。為什麼呢?因為當涉及到PSRemoting和WinRM時,通常只有一個原因會實施CredSSP,那就是”second hop problem”,下面你將了解到這個問題。

當配置了CredSSP身份驗證時,WinRM客戶端和服務器都使用Negotiate身份驗證來驗證用戶和客戶端。但一旦完成驗證,用戶的密碼就會被發送到服務器。

由於密碼是在驗證過程完成後發送的,所以它現在是加密的。CredSSP還使用TLS會話密鑰將密碼進行加密,以使加密字符串在會話之間是唯一的。

CredSSP很有幫助,因為在驗證後,服務器可以代表您連接到其他任何東西。然而,當這種情況發生時,您完全信任您連接到的服務器,並將用戶密碼交給它。

基於證書的身份驗證

可以說,與PSRemoting一起使用的最安全的身份驗證方法是基於證書的身份驗證。在這種身份驗證方法中,客戶端和服務器之間進行了典型的私鑰和公鑰的交換,以驗證證書的有效性。

WinRM 通過將伺服器上的使用者映射到 WinRM 內部來對使用者進行身份驗證。在身份驗證過程中,只傳遞公開金鑰,因此這是一種非常安全的身份驗證方式。

儘管是最安全的方式,但基於憑證的身份驗證並不常見。原因很簡單,需要進行一些繁瑣的設置工作。您需要:

  • 建立一個憑證授權機構
  • 創建一個使用者身份驗證憑證
  • 共享公開金鑰
  • 使用具有適當權限的本地使用者帳戶(可能是管理員組)
  • 設置 HTTPS 監聽器
  • …以及其他步驟。

即使客戶端和伺服器都是 Active Directory 的一部分,也無法使用網域使用者進行憑證驗證。

Windows OS 身份驗證預設值

現在您已經看到有很多不同的身份驗證選項可用,那麼您如何知道哪些是開箱即用的?下面的表格中有兩列,指示 WinRM 客戶端是否以及預設情況下該身份驗證類型是否已啟用。

所有上述的身份驗證類型都是可配置的,但使用下表將給您一個很好的概念,讓您知道需要自行配置的內容。

Method Client Service
Basic Enabled Disabled
Kerberos Enabled Enabled
Negotiate Enabled Enabled
CredSSP Disabled Disabled
Digest Enabled Disabled
Certificate Enabled Disabled
Windows OS Authentication Defaults

第二次跳躍問題或雙跳問題

PSRemoting面臨的最大問題之一是被稱為“第二次跳躍問題”或“雙跳問題”。這種情況發生在您通過PSRemoting連接到遠程系統後,需要再連接到另一台遠程計算機。

這種情況很棘手,因為當WinRm客戶端對第一個遠程計算機進行身份驗證時,服務器只驗證了起源客戶端的身份,而沒有將密碼發送到服務器。當您試圖從第一個連接的服務器連接到第二個計算機時,最終的服務器無法驗證用戶的身份。

您可以通過使用CredSSP或Kerberos委派來解決雙跳問題。

使用CredSSP

解決雙跳問題最常用的方法是使用CredSSP。CredSSP身份驗證通過在第一個遠程服務器上存儲用戶憑據,然後將這些憑據傳遞給第二個遠程服務器來解決這種情況。

然而,使用CredSSP有一個注意事項。存儲在第一個遠程服務器上的用戶憑據可能以明文形式存儲,從而引入明顯的安全問題。在更新的操作系統中,可以使用密碼的哈希值和Kerberos票據授權票據(TGT)一起進行身份驗證,就像明文密碼一樣,但這會降低一些風險。

通過Negotiate,客戶端和服務器互相傳遞信息以驗證其身份,但用戶的密碼永遠不可訪問。由於這種安全功能,第一個服務器無法在您連接到第二個服務器時對您進行身份驗證。

使用Kerberos委派

正如前面提到的,Kerberos是設置PSRemoting的常用方法。作為無處不在的Active Directory的一部分,並且默認情況下已經設置好,它非常常見。儘管Kerberos本身是一種很好的驗證WinRM的方式,但它無法解決雙跳問題。

為了解決雙跳場景,您可以使用第二種稱為Kerberos委派的認證方式。儘管有許多種類的Kerberos委派,但唯一能夠(並且足夠安全)作為CredSSP替代方案的是被稱為Kerberos受限 委派的特定類型,更具體地說是基於資源的Kerberos受限委派。

基於資源的Kerberos受限委派是一種根據域資源(如計算機)委派Kerberos驗證令牌的形式,這在這種情況下被限制為一個特定的Kerberos(Active Directory)對象列表。

要配置這個Kerberos委派,您需要編輯鏈中第三台計算機的ADComputer對象。例如,如果您要從ClientA遠程連接到ServerB再連接到ServerC,您需要編輯ServerC的ADComputer對象,但您也需要知道ServerB將是什麼。對於這個例子,在PowerShell中運行以下命令:

使用基於資源的Kerberos委派可用於遠程連接,例如…或…,但無法在使用PSRemoting的情況下運行。當使用PSRemoting通過WinRM從一台計算機連接到第三台計算機時,您將無法連接到第三台計算機。

設置基於資源的Kerberos受限委派只需一行PowerShell命令,使用Set-ADComputer cmdlet。例如,如果您通過PSRemoting從ClientA連接到ServerB,並且想要使用…連接到ServerC,可以運行以下PowerShell命令。

Set-ADComputer -Identity ServerC -PrincipalsAllowedToDelegateToAccount ServerB

WinRm緩存失敗的連接15分鐘。由於這個功能,即使設置了基於資源的Kerberos受限委派,您可能仍無法連接到第三台計算機。要解決此問題,請等待一段時間或在第三台計算機上運行命令klist purge -LI 0x3e7以清除失敗的Kerberos令牌。

如何使用SSH進行PSRemoting身份驗證的工作原理

儘管WinRm身份驗證是PSRemoting最常見的身份驗證方法,但從PowerShell v6開始,你還有另一種方式,即SSH。使用SSH作為身份驗證方法可讓你在Linux上使用PSRemoting。

與WinRm不同,SSH需要在客戶端和服務器上進行一些額外的配置,例如在Windows客戶端上設置SSH客戶端,以及…

使用SSH處理身份驗證意味著你只能使用SSH支持的身份驗證類型。這將使得支持的身份驗證類型列表縮小,主要有基於密碼和基於公鑰的兩種。

SSH支持其他類型的身份驗證,但通常被認為比基於密碼和基於公鑰的選項不太安全,因此我們只關注這兩種選項。

密碼身份驗證

使用基於密碼的身份驗證是設置SSH身份驗證與PSRemoting最簡單的方法。基於密碼的身份驗證允許你提供密碼來驗證自己。

在SSH身份验证过程中,密码在建立SSH连接后进行交换,并且密码在传输过程中进行了加密。与WinRM使用的某些身份验证方法(如Kerberos)不同,这种身份验证方法确实将整个密码发送到服务器。

你可以将SSH密码身份验证与使用HTTPS监听器的WinRM身份验证方法Basic进行比较。密码本身并没有以任何有意义的方式进行保护,但整个连接(包括密码)都是基于加密的,并且服务器是基于证书进行验证的。

基于证书的身份验证认证

虽然基于密码的身份验证易于设置和使用,但它存在两个问题。

  1. 首先,没有安全的方式在无人值守格式下进行身份验证。
  2. 密码身份验证仍然通过网络发送密码。虽然密码在SSH连接中进行了加密,但服务器接收到了完整的密码。如果服务器以某种方式被入侵,可能会成为安全问题。

另一方面,基于证书的身份验证不像密码那样在网络上发送任何敏感数据。相反,服务器有一个公钥的副本,客户端有一个私钥的副本,并且协商在服务器上进行。

A rough workflow goes as follows:

  1. 当客户端尝试进行身份验证时,它会向服务器发送公钥的ID或Thumbprint。
  2. 如果服务器将公钥列为已授权,则会用公钥加密的字符串进行响应。
  3. 然后客户端使用私钥解密该字符串。
  4. 私钥接着与会话 ID 进行哈希。
  5. 会话 ID 被发送回服务器,服务器使用原始字符串和会话 ID 生成的哈希值与之进行比较。
  6. 如果客户端的会话 ID 哈希与服务器上的会话 ID 匹配,客户端将通过认证并允许连接。

使用公钥加密的内容只能用相关的私钥解密。使用私钥加密的内容只能用公钥解密。会话 ID 的引入提供所谓的完美前向保密(PFS)。

如果私钥泄露,PFS 提供了安全性,攻击者将无法解密来来回回的所有消息。唯一的会话 ID 意味着用于加密通信的共享密钥对于每个会话都是不同的。

基于证书的 SSH 认证,例如 WinRm,确实需要额外的设置工作,如生成私钥/公钥对并在远程服务器上授权公钥。

连接所需的用户权限

默认情况下,有两个本地用户组可以使用 PSRemoting 远程连接到服务器:管理员远程管理用户

雖然您可以將使用者帳戶新增到遠端伺服器的本機管理員群組中,但應該始終提供最少的存取權限。如果使用者只需要連接到遠端電腦的PSRemoting,可以將使用者帳戶新增到遠端管理使用者群組,而不是管理員群組。

為了進一步控制PSRemoting的存取,還可以使用名為僅提供所需管理權限 (JEA)的功能。JEA允許非管理員使用者以PowerShell的受限語言模式運行特定命令作為管理員。

隱含 vs.「明確」遠程操作

如果您以前使用過PSRemoting,您可能熟悉像Invoke-CommandNew-PSSessionEnter-PSSession等命令。當您執行這些命令時,很明顯您是以某種方式連接到遠端電腦。您是明確地使用PSRemoting。

當您執行特定於PSRemoting的命令時,您是明確地執行這些命令,但您是否知道還有另一種方式?您可以利用隱含的PSRemoting,而不是直接呼叫Invoke-Command和其他命令。

隱式的 PSRemoting 可能看起來像是在你的 PowerShell 會話中本地執行命令,但實際上它們是在遠程機器上執行的。一個很好的例子是使用未在你的系統上安裝的模塊。而不是在本地安裝它,你可以從 PSSession 導出命令,這將使你能夠像在本地安裝了這些命令一樣運行它們。

在下面的截圖中,你可以看到我沒有 Test-PendingReboot 命令。然後,我連接到一台遠程機器並導出該命令。

Export-PSSession example

接下來,如果該模塊被導入,我就可以執行 Test-PendingReboot 命令。下面顯示了這一點,但你會注意到輸出中的計算機名稱不是 PowerShell 所在設備的名稱,而是導入命令的設備的名稱。

Implicit remoting in action

Source:
https://adamtheautomator.com/psremoting/