使用 PowerShell 管理 Windows 是當今的主流做法,這篇來分享我最近學到的 PowerShell 安全機制 - JEA,Just Enough Administration,恰到好處的系統管理。

傳統伺服器管理常用的授權高度特權帳號(高權帳號)做法有個隱憂,一旦駭客掌握了某個高權帳號,便有可能用它在組織內部四處橫行(資安術語叫「橫向移動」)為非作歹,高權帳號的權限愈大,產生的風險愈高。

資安哲學中有所謂「最小權限原則」(PoLP,Principle of Least Privilege),例如:若只給特定資料夾讀取權限就能做事,不要多給整個磁碟的寫入權限,如此即使帳號被駭客掌握,也無法會被用來讀取系統檔案或寫入惡意內容。

PowerShell 的 JEA 就是本著此最小權限原則概念所發展的技術,結合了 gMSA (延伸閱讀:使用 gMSA 讓 Windows 排程與服務帳號更安全)、WinRM、角色功能定義,實現一個「允許特定帳號開啟 PowerShell 遠端連線執行預先定義指令」的安全環境。

關於 JEA 的種種,MS Learn 是最權威最完整的參考來源,這篇文章則會用一個簡單實作 Lab 帶大家體驗 JEA 的設定與運作。

啟用 PowerShell 遠端管理

以管理者權限執行 Enable-PSRemoting 系統會自動設定 WinRM 並啟用對應的 Windows 防火牆例外規則 (預設啟用 HTTP 5985 Port,若要使用加密傳輸 HTTPS 5986 需另外手動設定)。

註:JEA 本質是一個受限制的 PowerShell 遠端端點(SessionType 為 RestrictedRemoteServer),使用者必須透過 Enter-PSSession 或 New-PSSession 等遠端命令連接,故依賴 WinRM 通訊協定、加密傳輸及其 ACL 權限管控。

建立角色功能檔 (Role Capability File)

下一步是建立角色功能檔 .psrc,定義角色及其可執行動作:

  1. 在 Program Files 建立一個新的 PowerShell 模組資料夾與 RoleCapabilities 子資料夾

    $modulePath = Join-Path $Env:ProgramFiles "WindowsPowerShell\Modules\JEALab"
    $rcFolder = Join-Path $modulePath "RoleCapabilities"
    New-Item -ItemType Directory -Path $rcFolder -Force
    
  2. 建立空的模組資訊清單 (至少需要一個與資料夾同名的檔案以識別為模組)

    $moduleManifestPath = Join-Path $modulePath "JEALab.psd1"
    New-ModuleManifest -Path $moduleManifestPath -RootModule "JEALab.psm1"
    
  3. 建立角色功能檔案

    $psrcPath = Join-Path $rcFolder "Maintenance.psrc"
    New-PSRoleCapabilityFile -Path $psrcPath
    
  4. 開啟 Maintenance.psrc 檔案列舉可執行的 Cmdlet
    尋找 VisibleCmdlets 範例位置,修改加入兩個指令 VisibleCmdlets = @('Get-Service', 'Restart-Service')

建立工作階段組態檔 (Session Configuration File)

工作階段組態檔(.pssc)定義誰可以存取 JEA 端點、他們被指派的角色,以及 JEA 在幕後用來執行命令的身分識別。

# 1. 定義角色對應 (將目前登入帳號對應到上面建立的 Maintenance 角色)
$roles = @{
    "$env:COMPUTERNAME\$env:USERNAME" = @{ RoleCapabilities = 'Maintenance' }
}

# 2. 定義組態檔參數
$parameters = @{
    # 設定使用 RestrictedRemoteServer 類型
    SessionType = 'RestrictedRemoteServer'
    # 指定路徑
    Path = '.\JEALabEndpoint.pssc'
    # 以本機虛擬帳號執行(具 Administrators 群組權限)
    RunAsVirtualAccount = $true
    RoleDefinitions = $roles
}

# 3. 產生組態檔
New-PSSessionConfigurationFile @parameters

# 4. 測試設定檔語法是否正確
Test-PSSessionConfigurationFile -Path .\JEALabEndpoint.pssc

註:RunAsVirtualAccount 指定虛擬帳號執行,預設會具有 Administrators 群組權限,但可另外指定 RunAsVirtualAccountGroups 指定權限較小的群組。參考

註冊 JEA 端點與連線測試

做好 .psrc 與 .pssc,最後一步是向系統註冊此 JEA 端點,以下指令可完成註冊並重新啟動 WinRM 服務,讓 JEA 端點正式啟用。

Register-PSSessionConfiguration -Path .\JEALabEndpoint.pssc -Name 'JEALabEndpoint' -Force

接著做幾個簡單測試:

# 連線到剛才建立的 JEA 端點
Enter-PSSession -ComputerName 'localhost' -ConfigurationName 'JEALabEndpoint'
# 只會看到 Get-Service 與 Restart-Service
Get-Command
# Get-Service 可正常執行
Get-Service
# 不在白名單的 Get-Process 會出現錯誤
Get-Process
# 不允許使用變數及程式語言指令 (RestrictedRemoteServer 為 NoLanguage 模式)
$test = 1
# 結束連線
Eixt-PSSession

測試成功!

解除註冊 JEA 端點

要移除以上建立的實驗環境,可以執行 Unregister-PSSessionConfiguration -Name 'JEALabEndpoint' -Force 取消註冊。

遠端連線

要從另一台電腦(用戶端/遠端主機)連線到 JEALabEndpoint 所在伺服器,若雙方隸屬相同網域,且登入身分為角色對應指定的網域帳號,則用 Enter-PSSession -ComputerName 'JEA伺服器名稱' -ConfigurationName 'JEALabEndpoint' 即可連線,Windows 會自動處理使用者及伺服器的 Kerberos 身分驗證;若為工作群組或不同網域,則需要額外步驟:

  1. 將 JEA 伺服器加入 WinRM 的「信任的主機 (TrustedHosts)」清單:Set-Item WSMan:\localhost\Client\TrustedHosts -Value <JEA伺服器IP或電腦名稱>
  2. 連線時指定身分識別:Enter-PSSession -ComputerName '<JEA伺服器IP>' -ConfigurationName 'JEALabEndpoint' -Credential (Get-Credential)

Introduces PowerShell Just Enough Administration (JEA) and least-privilege server management. Walks through a hands-on lab enabling remoting, defining role capabilities, creating session configurations, registering a JEA endpoint, and testing restricted remote commands.


Comments

Be the first to post a comment

Post a comment