JEA エンドポイントを作成するときに、JEA セッションでユーザーに許可する操作を説明するロール機能を 1 つ以上定義する必要があります。 ロール機能は、 .psrc
拡張子を持つ PowerShell データ ファイルで、接続しているユーザーが使用できるすべてのコマンドレット、関数、プロバイダー、および外部プログラムを一覧表示します。
許可するコマンドを決定する
ロール機能ファイルを作成する最初の手順は、ユーザーがアクセスする必要がある内容を検討することです。 要件の収集プロセスには時間がかかる場合がありますが、重要です。 ユーザーにアクセスできるコマンドレットと関数が少なすぎると、ユーザーが自分のジョブを完了できなくなる可能性があります。 多すぎるコマンドレットや関数へのアクセスを許可すると、ユーザーは意図した以上のことを行い、セキュリティの姿勢を弱めることができます。
このプロセスの実行方法は、組織と目標によって異なります。 次のヒントは、正しいパスを使用していることを確認するのに役立ちます。
- ユーザーがジョブを完了するために使用しているコマンドを特定します。 これには、IT スタッフの調査、自動化スクリプトの確認、PowerShell セッションのトランスクリプトとログの分析が含まれる場合があります。
- 最適な監査と JEA カスタマイズ エクスペリエンスを実現するために、コマンドライン ツールの使用を可能な限り PowerShell に更新します。 JEA のネイティブ PowerShell コマンドレットや関数ほど、外部プログラムを細かく制限することはできません。
- 特定のパラメーターまたはパラメーター値のみを許可するようにコマンドレットのスコープを制限します。 これは、ユーザーがシステムの一部のみを管理する必要がある場合に特に重要です。
- JEA で制約が困難な複雑なコマンドを置き換えるカスタム関数を作成します。 複雑なコマンドをラップする単純な関数や、追加の検証ロジックを適用する関数は、管理者とエンド ユーザーの簡易性に対して追加の制御を提供できます。
- ユーザーまたは自動化サービスで、許可されるコマンドのスコープ付きリストをテストし、必要に応じて調整します。
潜在的に危険なコマンドの例
JEA エンドポイントでユーザーがアクセス許可を昇格できないようにするには、コマンドを慎重に選択することが重要です。
Von Bedeutung
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 コマンドレットを使用して、新しい PowerShell ロール機能ファイルを作成できます。
New-PSRoleCapabilityFile -Path .\MyFirstJEARole.psrc
作成したロール機能ファイルを編集して、ロールに必要なコマンドのみを許可する必要があります。 PowerShell ヘルプ ドキュメントには、ファイルの構成例が含まれています。
PowerShell コマンドレットと関数の許可
ユーザーが PowerShell コマンドレットまたは関数を実行することを承認するには、コマンドレットまたは関数名を VisibleCmdlets または VisibleFunctions フィールドに追加します。 コマンドがコマンドレットか関数か不明な場合は、 Get-Command <name>
実行し、出力で CommandType プロパティを確認できます。
VisibleCmdlets = @('Restart-Computer', 'Get-NetIPAddress')
特定のコマンドレットまたは関数のスコープが、ユーザーのニーズに対して広すぎる場合があります。 たとえば、DNS 管理者は、DNS サービスを再起動するためにのみアクセスが必要な場合があります。 マルチテナント環境では、テナントはセルフサービス管理ツールにアクセスできます。 テナントは、独自のリソースの管理に限定する必要があります。 このような場合は、コマンドレットまたは関数から公開されるパラメーターを制限できます。
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 パラメーターは常に許可されます。 [パラメーター] フィールドに明示的に一覧表示しないでください。
次の一覧では、表示可能なコマンドレットまたは関数をカスタマイズするさまざまな方法について説明します。 VisibleCmdlets フィールドでは、以下のいずれかを組み合わせることができます。
ユースケース: パラメーターに制限を設けずに、ユーザーが
My-Func
を実行できるようにします。@{ Name = 'My-Func' }
ユースケース:パラメーターに制限を設けずに、ユーザーがモジュール
My-Func
からを実行できるようにします。@{ Name = 'MyModule\My-Func' }
ユースケース: ユーザーが動詞
My
を使用して任意のコマンドレットまたは関数を実行できるようにします。@{ Name = 'My-*' }
ユースケース: ユーザーが名詞
Func
を使用して任意のコマンドレットまたは関数を実行できるようにします。@{ Name = '*-Func' }
ユースケース:ユーザーが
My-Func
パラメーターとParam1
パラメーターを使用してParam2
を実行できるようにします。 パラメーターには、任意の値を指定できます。@{ Name = 'My-Func'; Parameters = @{ Name = 'Param1'}, @{ Name = 'Param2' }}
ユースケース:ユーザーが
My-Func
パラメーターを使用してParam1
を実行できるようにします。 パラメーターには、Value1
とValue2
のみを指定できます。@{ Name = 'My-Func' Parameters = @{ Name = 'Param1'; ValidateSet = @('Value1', 'Value2') } }
ユースケース:ユーザーが
My-Func
パラメーターを使用してParam1
を実行できるようにします。 パラメーターには、contoso
で始まる任意の値を指定できます。@{ Name = 'My-Func' Parameters = @{ Name = 'Param1'; ValidatePattern = 'contoso.*' } }
Warnung
ベスト セキュリティ プラクティスでは、表示されるコマンドレットまたは関数を定義するときにワイルドカードを使用することはお勧めしません。 代わりに、信頼できる各コマンドを明示的に一覧表示して、同じ名前付けスキームを共有する他のコマンドが意図せずに承認されないようにする必要があります。
ValidatePattern と ValidateSet の両方を同じコマンドレットまたは関数に適用することはできません。
その場合、 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 コマンドレットと関数で許可されるパラメーターを制御できるため、承認する外部実行可能ファイルに対して PowerShell コマンドレットまたは関数と同等の関数を使用します。
多くの実行可能ファイルを使用すると、現在の状態を読み取り、さまざまなパラメーターを指定して変更できます。
たとえば、システムでホストされているネットワーク共有を管理するファイル サーバー管理者の役割を考えてみましょう。 共有を管理する 1 つの方法は、 net share
を使用することです。 ただし、ユーザーがコマンドを使用してコマンド net.exe
で管理者特権を取得できるため、net group Administrators unprivilegedjeauser /add
を許可することは危険です。 より安全なオプションは、 Get-SmbShare コマンドレットを許可することです。このコマンドレットは同じ結果を達成しますが、スコープははるかに制限されています。
JEA セッションでユーザーが外部コマンドを使用できるようにする場合は、常に実行可能ファイルへの完全なパスを指定します。 これにより、システム上の他の場所にある、同様の名前と潜在的に悪意のあるプログラムが実行されるのを防ぐことができます。
PowerShell プロバイダーへのアクセスを許可する
既定では、JEA セッションでは PowerShell プロバイダーを使用できません。 これにより、機密情報と構成設定が接続ユーザーに開示されるリスクが軽減されます。
必要に応じて、 VisibleProviders
コマンドを使用して PowerShell プロバイダーへのアクセスを許可できます。 プロバイダーの完全な一覧については、 Get-PSProvider
を実行します。
VisibleProviders = 'Registry'
ファイル システム、レジストリ、証明書ストア、またはその他の機密性の高いプロバイダーへのアクセスを必要とする単純なタスクの場合は、ユーザーの代わりにプロバイダーと連携するカスタム関数を記述することを検討してください。 JEA セッションで使用できる関数、コマンドレット、および外部プログラムには、JEA と同じ制約はありません。 既定では、任意のプロバイダーにアクセスできます。 また、ユーザーが JEA エンドポイント間でファイルをコピーする必要がある場合は、 ユーザー ドライブ の使用も検討してください。
カスタム関数の作成
ロール機能ファイルでカスタム関数を作成して、エンド ユーザーの複雑なタスクを簡略化できます。 カスタム関数は、コマンドレット パラメーター値の高度な検証ロジックが必要な場合にも便利です。 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
}
}
Von Bedeutung
JEA ユーザーが実行できるように、カスタム関数の名前を VisibleFunctions フィールドに追加することを忘れないでください。
カスタム関数の本文 (スクリプト ブロック) は、システムの既定の言語モードで実行され、JEA の言語制約の対象になりません。 つまり、関数はファイル システムとレジストリにアクセスし、ロール機能ファイルに表示されなかったコマンドを実行できます。 パラメーターを使用する場合は、任意のコードを実行しないように注意してください。
Invoke-Expression
などのコマンドレットにユーザー入力を直接パイプしないようにします。
上記の例では、短縮形のMicrosoft.PowerShell.Utility\Select-Object
の代わりに完全修飾モジュール名 (FQMN) Select-Object
が使用されていることに注意してください。
ロール機能ファイルで定義されている関数は引き続き JEA セッションのスコープの対象となります。これには、JEA が既存のコマンドを制約するために作成するプロキシ関数が含まれます。
既定では、 Select-Object
は、オブジェクトに対する任意のプロパティの選択を許可しないすべての JEA セッションの制約付きコマンドレットです。 制約のない Select-Object
を関数で使用するには、FQMN を使用して完全な実装を明示的に要求する必要があります。 JEA セッション内の制約付きコマンドレットは、関数から呼び出されたときと同じ制約を持ちます。 詳細については、about_Command_Precedenceを参照してください。
複数のカスタム関数を記述している場合は、PowerShell スクリプト モジュールに配置する方が便利です。 組み込みモジュールやサード パーティ製モジュールと同様に、 VisibleFunctions フィールドを使用して、JEA セッションでこれらの関数を表示できるようにします。
JEA セッションでタブ補完を正しく機能させるには、組み込みの関数TabExpansion2
を VisibleFunctions リストに含める必要があります。
構成でロール機能を使用できるようにする
PowerShell 6 より前では、PowerShell でロール機能ファイルを検索するには、PowerShell モジュールの RoleCapabilities
フォルダーに格納する必要があります。 モジュールは、 $Env:PSModulePath
環境変数に含まれる任意のフォルダーに格納できますが、 $Env:SystemRoot\System32
や信頼されていないユーザーがファイルを変更できるフォルダーに配置しないでください。
次の例では、ロール機能ファイルをホストする パスに $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 セッションには、変更された機能が反映されます。
これが、ロール機能フォルダーへのアクセスの制御が非常に重要な理由です。 ロール機能ファイルの変更を許可する必要があるのは、高信頼の管理者だけです。 信頼されていないユーザーがロール機能ファイルを変更できる場合は、特権を昇格できるコマンドレットに簡単にアクセスできます。
ロール機能へのアクセスをロックダウンしようとしている管理者の場合は、ローカル システムにロール機能ファイルと含まれるモジュールへの読み取り専用アクセス権があることを確認します。
ロール機能のマージ方法
ユーザーは、JEA セッションに入ると、 セッション構成ファイル 内のすべての一致するロール機能へのアクセス権が付与されます。 JEA は、ユーザーに、どのロールでも許可される最も制限の少ないコマンド セットを提供しようとします。
VisibleCmdlets と VisibleFunctions
最も複雑なマージ ロジックは、JEA でパラメーターとパラメーター値を制限できるコマンドレットと関数に影響します。
規則は次のとおりです。
- コマンドレットが 1 つのロールでのみ表示される場合は、適用可能なパラメーター制約を持つユーザーに表示されます。
- 1 つのコマンドレットが複数のロールで表示され、各ロールがコマンドレットに対して同じ制約を持つ場合、そのコマンドレットはそれらの制約を持つユーザーに表示されます。
- コマンドレットが複数のロールで表示され、各ロールで異なるパラメーター のセットが許可されている場合、コマンドレットとすべてのロールで定義されているすべてのパラメーターがユーザーに表示されます。 1 つのロールにパラメーターに制約がない場合は、すべてのパラメーターが許可されます。
- 1 つのロールがコマンドレット パラメーターの検証セットまたは検証パターンを定義し、もう 1 つのロールでパラメーターを許可するがパラメーター値を制約しない場合、検証セットまたはパターンは無視されます。
- 複数のロールで同じコマンドレット パラメーターに対して検証セットが定義されている場合、すべての検証セットのすべての値が許可されます。
- 複数のロールで同じコマンドレット パラメーターに対して検証パターンが定義されている場合は、いずれかのパターンに一致する値が許可されます。
- 検証セットが 1 つ以上のロールで定義されていて、同じコマンドレット パラメーターに対して検証パターンが別のロールで定義されている場合、検証セットは無視され、ルール (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 ユーザーは、1 つのロール機能で使用できるコマンド、エイリアス、プロバイダー、またはスクリプトを使用できます。
あるロール機能と、別のロール機能のコマンドレット/関数/コマンドを組み合わせたプロバイダーのセットで、ユーザーがシステム リソースに意図せずにアクセスできないように注意してください。
たとえば、1 つのロールで Remove-Item
コマンドレットが許可され、もう 1 つで FileSystem
プロバイダーが許可されている場合、JEA ユーザーがコンピューター上の任意のファイルを削除するリスクがあります。 ユーザーの有効なアクセス許可の識別に関する追加情報については、 監査 JEA の記事を参照してください。
次のステップ
PowerShell