共用方式為


JEA 角色功能

建立 JEA 端點時,您必須定義一或多個角色功能,以描述某人在 JEA 工作階段中可以執行的動作。 角色功能是具有擴充功能的PowerShell資料檔 .psrc ,可列出可供連接使用者使用的所有 Cmdlet、函式、提供者和外部程式。

判斷要允許的命令

建立角色功能檔案的第一個步驟是考慮使用者需要存取權。 需求收集程式可能需要一段時間,但很重要。 讓使用者存取太多 Cmdlet 和函式,可以防止他們完成工作。 允許存取太多 Cmdlet 和函式,可讓使用者執行比您預期的更多動作,並削弱您的安全性立場。

您處理此程式的方式取決於您的組織和目標。 下列秘訣可協助您確定您位於正確的路徑上。

  1. 識別 使用者用來完成作業的命令。 這可能涉及調查 IT 人員、檢查自動化腳本,或分析 PowerShell 會話文字記錄和記錄。
  2. 盡可能將命令行工具的使用更新 為 PowerShell 對等專案,以獲得最佳稽核和 JEA 自定義體驗。 外部程式無法像 JEA 中的原生 PowerShell Cmdlet 和函式一樣細微地限制。
  3. 限制 Cmdlet 的範圍只允許特定參數或參數值。 如果用戶應該只管理系統的一部分,這特別重要。
  4. 建立 自定義函式來取代在 JEA 中難以限制的複雜命令或命令。 包裝複雜命令或套用其他驗證邏輯的簡單函式,可以為系統管理員和用戶簡化提供額外的控制。
  5. 使用您的使用者或自動化服務測試 允許命令的範圍清單,並視需要進行調整。

潛在危險命令的範例

請務必仔細選取命令,以確保 JEA 端點不允許使用者提高其許可權。

重要

JEA 會話中使用者 successCommands 所需的基本資訊通常會以較高的許可權執行。

下列清單包含命令範例,如果處於不受限制的狀態允許,則可以惡意使用。 這不是詳盡的清單,只能作為警告起點。

  • 風險: 授與連線用戶系統管理員許可權以略過 JEA

    範例:

    Add-LocalGroupMember -Member 'CONTOSO\jdoe' -Group 'Administrators'
    

    相關命令:

    • Add-ADGroupMember
    • Add-LocalGroupMember
    • net.exe
    • dsadd.exe
  • 風險: 執行任意程序代碼,例如惡意代碼、惡意探索或自定義腳本以略過保護

    範例:

    Start-Process -FilePath '\\san\share\malware.exe'
    

    相關命令:

    • Start-Process
    • New-Service
    • Invoke-Item
    • Invoke-WmiMethod
    • Invoke-CimMethod
    • Invoke-Expression
    • Invoke-Command
    • New-ScheduledTask
    • Register-ScheduledJob

建立角色功能檔案

您可以使用 New-PSRoleCapabilityFile Cmdlet 建立新的 PowerShell 角色功能檔案。

New-PSRoleCapabilityFile -Path .\MyFirstJEARole.psrc

您應該編輯已建立的角色功能檔案,只允許角色所需的命令。 PowerShell 說明文件包含數個有關如何設定檔案的範例。

允許 PowerShell Cmdlet 和函式

若要授權使用者執行 PowerShell Cmdlet 或函式,請將 Cmdlet 或函式名稱新增至 VisibleCmdlets 或 VisibleFunctions 字段。 如果您不確定命令是否為 Cmdlet 或函式,您可以執行 Get-Command <name> 並檢查 輸出中的 CommandType 屬性。

VisibleCmdlets = @('Restart-Computer', 'Get-NetIPAddress')

有時候特定 Cmdlet 或函式的範圍太寬,無法滿足使用者的需求。 例如,DNS 系統管理員可能只需要存取權才能重新啟動 DNS 服務。 在多租用戶環境中,租使用者可以存取自助管理工具。 租使用者應受限於管理自己的資源。 在這些情況下,您可以限制從 Cmdlet 或函式公開哪些參數。

VisibleCmdlets = @{
    Name       = 'Restart-Computer'
    Parameters = @{ Name = 'Name' }
}

在更進階的案例中,您可能也需要限制使用者可搭配這些參數使用的值。 角色功能可讓您定義一組值或正則表達式模式,以決定允許哪些輸入。

VisibleCmdlets = @(
    @{
        Name       = 'Restart-Service'
        Parameters = @{ Name = 'Name'; ValidateSet = @('Dns', 'Spooler') }
    }
    @{
        Name       = 'Start-Website'
        Parameters = @{ Name = 'Name'; ValidatePattern = 'HR_*' }
    }
)

注意

即使您限制可用的參數,也一律允許常見的 PowerShell 參數。 您不應該在 [參數] 字段中明確列出它們。

下列清單說明您可以自定義可見 Cmdlet 或函式的各種方式。 您可以在 [VisibleCmdlet] 字段中混合並比對下列 任何一項

  • 使用案例: 允許使用者在不限制參數的情況下執行 My-Func

    @{ Name = 'My-Func' }
    
  • 使用案例:允許使用者從模組 MyModule 執行My-Func,而不受參數的任何限制。

    @{ Name = 'MyModule\My-Func' }
    
  • 使用案例: 允許使用者使用動詞 My來執行任何 Cmdlet 或 函式。

    @{ Name = 'My-*' }
    
  • 使用案例: 允許使用者以名詞 Func執行任何 Cmdlet 或函式。

    @{ Name = '*-Func' }
    
  • 使用案例:允許使用者使用 Param1Param2 參數執行My-Func。 任何值都可以提供給參數。

    @{ Name = 'My-Func'; Parameters = @{ Name = 'Param1'}, @{ Name = 'Param2' }}
    
  • 使用案例:允許使用者使用 Param1 參數執行My-Func。 只能 Value1 將和 Value2 提供給 參數。

    @{
        Name       = 'My-Func'
        Parameters = @{ Name = 'Param1'; ValidateSet = @('Value1', 'Value2') }
    }
    
  • 使用案例:允許使用者使用 Param1 參數執行My-Func。 開頭 contoso 的任何值都可以提供給 參數。

    @{
        Name       = 'My-Func'
        Parameters = @{ Name = 'Param1'; ValidatePattern = 'contoso.*' }
    }
    

警告

為了獲得最佳安全性作法,在定義可見的 Cmdlet 或函式時,不建議使用通配符。 相反地,您應該明確列出每個受信任的命令,以確保沒有其他共用相同命名配置的命令無意中獲得授權。

您無法將 ValidatePatternValidateSet 同時套用至相同的 Cmdlet 或函式。

如果您這樣做, ValidatePattern覆寫 ValidateSet

如需 ValidatePattern 的詳細資訊,請參閱Hey、Scripting Guy! 文章PowerShell 正則表達式參考內容。

允許外部命令和 PowerShell 腳本

若要允許使用者在 JEA 會話中執行可執行檔和 PowerShell 腳稿 (.ps1),您必須將完整路徑新增至 VisibleExternalCommands 欄位中的每個程式

VisibleExternalCommands = @(
    'C:\Windows\System32\whoami.exe'
    'C:\Program Files\Contoso\Scripts\UpdateITSoftware.ps1'
)

可能的話,請針對您授權的任何外部可執行檔使用PowerShell Cmdlet或函式對等專案,因為您可以控制PowerShell Cmdlet和函式所允許的參數。

許多可執行檔可讓您讀取目前的狀態,然後藉由提供不同的參數加以變更。

例如,請考慮管理系統上裝載之網路共享的檔伺服器管理員角色。 管理共用的其中一種方式是使用 net share。 不過,允許 net.exe 很危險,因為使用者可以使用 命令來取得命令 net group Administrators unprivilegedjeauser /add的系統管理員許可權。 更安全的選項是允許 Get-SmbShare Cmdlet,這可達到相同的結果,但範圍會更加有限。

將外部命令提供給 JEA 工作階段中的使用者時,請一律指定可執行檔的完整路徑。 這可防止執行位於系統上其他地方的類似具名和潛在惡意程式。

允許存取 PowerShell 提供者

根據預設,JEA 會話中沒有可用的 PowerShell 提供者。 這樣可降低敏感性資訊和組態設定向連線使用者揭露的風險。

必要時,您可以使用 命令來允許存取 PowerShell 提供者 VisibleProviders 。 如需完整的提供者清單,請執行 Get-PSProvider

VisibleProviders = 'Registry'

對於需要存取文件系統、登錄、證書存儲或其他敏感性提供者的簡單工作,請考慮撰寫代表使用者與提供者搭配使用的自定義函式。 JEA 會話中可用的函式、Cmdlet 和外部程式不會受限於與 JEA 相同的條件約束。 他們預設可以存取任何提供者。 也請考慮在使用者需要將檔案複製到 JEA 端點或從 JEA 端點複製檔案時使用 使用者磁碟驅動器

建立自定義函式

您可以在角色功能檔案中撰寫自定義函式,以簡化用戶的複雜工作。 當您需要 Cmdlet 參數值的進階驗證邏輯時,自定義函式也很有用。 您可以在 FunctionDefinitions 欄位撰寫簡單的函式:

VisibleFunctions = 'Get-TopProcess'

FunctionDefinitions = @{
    Name        = 'Get-TopProcess'
    ScriptBlock = {
        param($Count = 10)

        Get-Process |
            Sort-Object -Property CPU -Descending |
            Microsoft.PowerShell.Utility\Select-Object -First $Count
    }
}

重要

別忘了將自定義函式的名稱新增至 VisibleFunctions 欄位,以便由 JEA 使用者執行。

自定義函式的主體(文本區塊)會以系統的默認語言模式執行,而且不受 JEA 的語言限制。 這表示函式可以存取檔案系統和登錄,並執行未在角色功能檔案中顯示之命令。 請小心避免在使用參數時執行任意程序代碼。 避免直接將使用者輸入管線傳送至 Cmdlet,例如 Invoke-Expression

在上述範例中,請注意已使用完整模組名稱 (FQMN) Microsoft.PowerShell.Utility\Select-Object ,而不是縮寫 Select-Object。 角色功能檔案中定義的函式仍受限於 JEA 會話的範圍,其中包括 JEA 建立的 Proxy 函式,以限制現有的命令。

根據預設, Select-Object 是所有 JEA 會話中不允許在對象上選取任意屬性的限制 Cmdlet。 若要在函式中使用不受限制 Select-Object 的 函式,您必須使用 FQMN 明確要求完整實作。 JEA 會話中的任何限制 Cmdlet 在從函式叫用時具有相同的條件約束。 如需詳細資訊,請參閱 about_Command_Precedence

如果您要撰寫數個自定義函式,將函式放在PowerShell腳本模組中會比較方便。 您可以使用 VisibleFunctions 欄位在 JEA 會話中顯示這些函式,就像使用內建和第三方模組一樣。

若要讓索引標籤自動完成在 JEA 工作階段中正常運作,您必須在 VisibleFunctions 清單中包含內tabexpansion2建函式。

讓角色功能可供設定使用

在 PowerShell 6 之前,若要讓 PowerShell 尋找角色功能檔案,它必須儲存在 RoleCapabilities PowerShell 模組中的資料夾中。 模組可以儲存在環境變數中包含的 $env:PSModulePath 任何資料夾中,不過您不應該將它 $env:SystemRoot\System32 放在 或不受信任的使用者可以修改檔案的資料夾。

下列範例會在裝載角色功能檔案的路徑中建立名為 ContosoJEA$env:ProgramFiles PowerShell 腳本模組。

# Create a folder for the module
$modulePath = Join-Path $env:ProgramFiles "WindowsPowerShell\Modules\ContosoJEA"
New-Item -ItemType Directory -Path $modulePath

# Create an empty script module and module manifest.
# At least one file in the module folder must have the same name as the folder itself.
$rootModulePath = Join-Path $modulePath "ContosoJEAFunctions.psm1"
$moduleManifestPath = Join-Path $modulePath "ContosoJEA.psd1"
New-Item -ItemType File -Path $RootModulePath
New-ModuleManifest -Path $moduleManifestPath -RootModule "ContosoJEAFunctions.psm1"

# Create the RoleCapabilities folder and copy in the PSRC file
$rcFolder = Join-Path $modulePath "RoleCapabilities"
New-Item -ItemType Directory $rcFolder
Copy-Item -Path .\MyFirstJEARole.psrc -Destination $rcFolder

如需 PowerShell 模組的詳細資訊,請參閱 瞭解 PowerShell 模組

從 PowerShell 6 開始, RoleDefinitions 屬性已新增至會話組態檔。 此屬性可讓您指定角色定義的角色組態檔位置。 請參閱 New-PSSessionConfigurationFile 中的範例。

更新角色功能

您可以編輯角色功能檔案,隨時更新設定。 在角色功能更新之後啟動的任何新的 JEA 會話,都會反映修訂的功能。

這就是為什麼控制角色功能資料夾的存取是如此重要。 只應允許高度信任的系統管理員變更角色功能檔案。 如果不受信任的使用者可以變更角色功能檔案,他們可以輕鬆地授與 Cmdlet 的存取權,讓他們提升其許可權。

對於想要鎖定角色功能存取權的系統管理員,請確定本機系統具有角色功能檔案和包含模組的唯讀存取權。

如何合併角色功能

當使用者輸入 JEA 工作階段時,會獲得工作階段組態檔所有相符角色功能的存取權。 JEA 會嘗試為使用者提供任何角色所允許的最寬鬆命令集。

VisibleCmdlet 和 VisibleFunctions

最複雜的合併邏輯會影響 Cmdlet 和函式,這些 Cmdlet 和函式可以在 JEA 中限制其參數和參數值。

規則如下:

  1. 如果 Cmdlet 只在一個角色中顯示,則使用者可以看到任何適用的參數條件約束。
  2. 如果 Cmdlet 在多個角色中可見,而且每個角色在 Cmdlet 上都有相同的條件約束,則具有這些條件約束的使用者可以看到 Cmdlet。
  3. 如果 Cmdlet 在多個角色中可見,而且每個角色都允許不同的參數集,則使用者可以看到跨每個角色定義的 Cmdlet 和所有參數。 如果一個角色沒有參數的條件約束,則會允許所有參數。
  4. 如果其中一個角色定義 Cmdlet 參數的驗證集或驗證模式,而另一個角色允許參數,但不會限制參數值,則會忽略驗證集或模式。
  5. 如果在多個角色中為相同的 Cmdlet 參數定義驗證集,則會允許來自所有驗證集的所有值。
  6. 如果已針對多個角色中的相同 Cmdlet 參數定義驗證模式,則允許符合任何模式的任何值。
  7. 如果在一或多個角色中定義驗證集,而且驗證模式定義於相同 Cmdlet 參數的另一個角色中,則會忽略驗證集,而規則 (6) 會套用至其餘的驗證模式。

以下是如何根據下列規則合併角色的範例:

# Role A Visible Cmdlets
$roleA = @{
    VisibleCmdlets = @(
        'Get-Service'
         @{
            Name       = 'Restart-Service'
            Parameters = @{ Name = 'DisplayName'; ValidateSet = 'DNS Client' }
        }
    )
}

# Role B Visible Cmdlets
$roleB = @{
    VisibleCmdlets = @(
        @{
            Name       = 'Get-Service';
            Parameters = @{ Name = 'DisplayName'; ValidatePattern = 'DNS.*' }
        }
        @{
            Name       = 'Restart-Service'
            Parameters = @{ Name = 'DisplayName'; ValidateSet = 'DNS Server' }
        }
    )
}

# Resulting permissions for a user who belongs to both role A and B
# - The constraint in role B for the DisplayName parameter on Get-Service
#   is ignored because of rule #4
# - The ValidateSets for Restart-Service are merged because both roles use
#   ValidateSet on the same parameter per rule #5
$mergedAandB = @{
    VisibleCmdlets = @(
        'Get-Service'
        @{
            Name = 'Restart-Service';
            Parameters = @{
                Name = 'DisplayName'
                ValidateSet = 'DNS Client', 'DNS Server'
            }
        }
    )
}

VisibleExternalCommands、VisibleAliases、VisibleProviders、ScriptsToProcess

角色功能檔案中的所有其他欄位都會新增至一組累計允許的外部命令、別名、提供者和啟動腳本。 JEA 使用者可以使用單一角色功能中的任何命令、別名、提供者或腳本。

請小心,確保一組來自某個角色功能的提供者和來自另一個角色的 Cmdlet/functions/命令的組合,不允許使用者無意存取系統資源。 例如,如果某個角色允許 Remove-Item Cmdlet,而另一個角色允許 FileSystem 提供者,您就有可能在計算機上刪除任意檔案。 如需識別使用者有效許可權的其他資訊,請參閱 稽核 JEA 一文。

下一步

建立工作階段組態檔