PowerShell リモート処理での次ホップの実行
"次ホップの問題" とは次のような状況のことです。
- ServerA にログインしています。
- ServerA からリモート PowerShell セッションを開始して ServerB に接続します。
- PowerShell リモート処理セッションを介して ServerB で実行するコマンドは、ServerC 上のリソースにアクセスを試みます。
- PowerShell リモート処理セッションの作成に使用した資格情報が ServerB から ServerC に渡されないため、ServerC 上のリソースへのアクセスは拒否されます。
この問題に対処する方法はいくつかあります。 次の表に、優先順位順に方法の一覧を示します。
構成 | Note |
---|---|
CredSSP | 使いやすさとセキュリティのバランスが取れている |
リソースに基づく Kerberos の制約付き委任 | 単純な構成で高いセキュリティ |
Kerberos の制約付き委任 | セキュリティは高いが、ドメイン管理者が必要 |
Kerberos の委任 (無制限) | 推奨されません |
Just Enough Administration (JEA) | セキュリティは最も高いが、より詳細な構成が必要 |
RunAs を使用する PSSessionConfiguration | 簡単に構成できるが、資格情報の管理が必要 |
Invoke-Command スクリプト ブロックの内部で資格情報を渡す |
最も簡単に使用できるが、資格情報を指定する必要がある |
CredSSP
認証に資格情報のセキュリティ サポート プロバイダー (CredSSP) を使用できます。 CredSSP はリモート サーバー (ServerB) に資格情報をキャッシュするため、これを使用すると資格情報の盗難攻撃にさらされます。 リモート コンピューターが侵害されると、攻撃者はユーザーの資格情報にアクセスできます。 CredSSP は、既定では、クライアント コンピューターとサーバー コンピューターの両方で無効になっています。 CredSSP は、最も信頼性の高い環境でのみ有効にしてください。 たとえば、ドメイン コントローラーは信頼性が高いため、ドメイン コントローラーに接続しているドメイン管理者が有効にすることをお勧めします。
PowerShell リモート処理で CredSSP を使用する場合のセキュリティに関する注意事項の詳細については、「Accidental Sabotage: Beware of CredSSP (予想外の妨害行為: CredSSP に関する注意事項)」を参照してください。
資格情報の盗難攻撃の詳細については、「Mitigating Pass-the-Hash (PtH) Attacks and Other Credential Theft (Pass-the-Hash (PtH) 攻撃とその他の資格情報の盗難の抑制)」を参照してください。
PowerShell リモート処理用に CredSSP を有効にして使用する方法の例については、「CredSSP を使用して PowerShell "次ホップ" 機能を有効にする」をご覧ください。
長所
- Windows Server 2008 以降のすべてのサーバーで機能します。
短所
- セキュリティの脆弱性があります。
- クライアント ロールとサーバー ロールの両方の構成が必要です。
- は、Protected Users グループでは機能しません。 詳細については、「Protected Users セキュリティ グループ」をご覧ください。
Kerberos の制約付き委任
従来の (リソースに基づかない) 制約付き委任を使って、次ホップを実行できます。 プロトコル遷移を許可するには、[任意の認証プロトコルを使う] オプションを使用して Kerberos の制約付き委任を構成します。
長所
- 特別なコーディングが必要ありません。
- 資格情報は格納されません。
短所
- WinRM の 2 番目のホップはサポートされていません。
- 構成には、ドメイン管理者のアクセス権が必要です。
- リモート サーバー (ServerB) の Active Directory オブジェクトで構成する必要があります。
- 1 つのドメインに制限されます。 ドメインまたはフォレストをまたがることはできません。
- オブジェクトとサービス プリンシパル名 (SPN) を更新する権限が必要です。
- ServerB は、ユーザーの介入なしに、ユーザーに代わって ServerC への Kerberos チケットを取得できます。
Note
アカウントが機密性が高く、 委任プロパティ セットを委任できない Active Directory アカウントは委任できません。 詳細については、「セキュリティ フォーカス: 特権アカウントと Kerberos 認証ツールと設定」の「アカウントは機密性が高く、委任できません」を分析する方法に関するページを参照してください。
リソースに基づく Kerberos の制約付き委任
リソースに基づく Kerberos の制約付き委任 (Windows Server 2012 で導入) を使って、リソースが存在するサーバー オブジェクトでの資格情報の委任を構成します。 上で説明した次ホップのシナリオでは、ServerC を構成して、どこから委任された資格情報の受け入れるかを指定します。
長所
- 資格情報は格納されません。
- PowerShell コマンドレットを使用して構成します。 特別にコードを記述する必要がありません。
- 構成にドメイン管理者のアクセス権は必要ありません。
- 複数のドメインおよびフォレストをまたいで動作します。
短所
- Windows Server 2012 以降が必要です。
- WinRM の 2 番目のホップはサポートされていません。
- オブジェクトとサービス プリンシパル名 (SPN) を更新する権限が必要です。
Note
アカウントが機密性が高く、 委任プロパティ セットを委任できない Active Directory アカウントは委任できません。 詳細については、「セキュリティ フォーカス: 特権アカウントと Kerberos 認証ツールと設定」の「アカウントは機密性が高く、委任できません」を分析する方法に関するページを参照してください。
例
ServerB からの委任された資格情報を許可するように ServerC でリソースに基づく制約付き委任を構成する PowerShell の例を示します。 この例では、すべてのサーバーが Windows Server 2012 以降を実行しており、いずれかのサーバーが属している各ドメインに少なくとも 1 つの Windows Server 2012 ドメイン コントローラーがあるものとします。
制約付き委任を構成する前に、RSAT-AD-PowerShell
機能を追加して Active Directory PowerShell モジュールをインストールした後、そのモジュールをセッションにインポートする必要があります。
Add-WindowsFeature RSAT-AD-PowerShell
Import-Module ActiveDirectory
Get-Command -ParameterName PrincipalsAllowedToDelegateToAccount
使用できる複数のコマンドレットに、PrincipalsAllowedToDelegateToAccount パラメーターが追加されています。
CommandType Name ModuleName
----------- ---- ----------
Cmdlet New-ADComputer ActiveDirectory
Cmdlet New-ADServiceAccount ActiveDirectory
Cmdlet New-ADUser ActiveDirectory
Cmdlet Set-ADComputer ActiveDirectory
Cmdlet Set-ADServiceAccount ActiveDirectory
Cmdlet Set-ADUser ActiveDirectory
PrincipalsAllowedToDelegateToAccount パラメーターは、Active Directory オブジェクトの msDS-AllowedToActOnBehalfOfOtherIdentity 属性を設定します。この属性には、関連付けられたアカウント (この例では、Server のコンピューター アカウント) に資格情報を委任する権限を持つアカウントを指定するアクセス制御リスト (ACL) が含まれます。
サーバーを表すために使用する変数を設定します。
# Set up variables for reuse
$ServerA = $env:COMPUTERNAME
$ServerB = Get-ADComputer -Identity ServerB
$ServerC = Get-ADComputer -Identity ServerC
WinRM (したがって PowerShell リモート処理) は、既定でコンピューター アカウントとして実行します。 これは、winrm
サービスの StartName プロパティを見て確認できます。
Get-CimInstance Win32_Service -Filter 'Name="winrm"' | Select-Object StartName
StartName
---------
NT AUTHORITY\NetworkService
ServerC で ServerB の PowerShell リモート処理セッションからの委任を許可するため、ServerC の PrincipalsAllowedToDelegateToAccount パラメーターを ServerB のコンピューター オブジェクトに設定する必要があります。
# Grant resource-based Kerberos constrained delegation
Set-ADComputer -Identity $ServerC -PrincipalsAllowedToDelegateToAccount $ServerB
# Check the value of the attribute directly
$x = Get-ADComputer -Identity $ServerC -Properties msDS-AllowedToActOnBehalfOfOtherIdentity
$x.'msDS-AllowedToActOnBehalfOfOtherIdentity'.Access
# Check the value of the attribute indirectly
Get-ADComputer -Identity $ServerC -Properties PrincipalsAllowedToDelegateToAccount
Kerberos のキー配布センター (KDC) は、拒否されたアクセス試行を 15 分間キャッシュします (ネガティブ キャッシュ)。 ServerB が以前に ServerC にアクセスしようとした場合は、次のコマンドを呼び出して、ServerB 上のキャッシュをクリアする必要があります。
Invoke-Command -ComputerName $ServerB.Name -Credential $cred -ScriptBlock {
klist purge -li 0x3e7
}
キャッシュを消去するには、コンピューターを再起動するか、15 分以上待つのでもかまいません。
キャッシュをクリアした後は、ServerA から ServerB を経由して ServerC にコードを正常に実行できます。
# Capture a credential
$cred = Get-Credential Contoso\Alice
# Test kerberos double hop
Invoke-Command -ComputerName $ServerB.Name -Credential $cred -ScriptBlock {
Test-Path \\$($using:ServerC.Name)\C$
Get-Process lsass -ComputerName $($using:ServerC.Name)
Get-EventLog -LogName System -Newest 3 -ComputerName $($using:ServerC.Name)
}
この例では、ServerB が $ServerC
変数を認識できるようにするため、$using
変数を使用しています。
$using
変数については、「About Remote Variables」 (リモート変数について) を参照してください。
複数のサーバーが ServerC に資格情報を委任できるようにするには、ServerC で PrincipalsAllowedToDelegateToAccount パラメーターの値に配列を設定します。
# Set up variables for each server
$ServerB1 = Get-ADComputer -Identity ServerB1
$ServerB2 = Get-ADComputer -Identity ServerB2
$ServerB3 = Get-ADComputer -Identity ServerB3
$ServerC = Get-ADComputer -Identity ServerC
$servers = @(
$ServerB1,
$ServerB2,
$ServerB3
)
# Grant resource-based Kerberos constrained delegation
Set-ADComputer -Identity $ServerC -PrincipalsAllowedToDelegateToAccount $servers
ドメイン間で 2 番目のホップを行う場合は、 Server パラメーターを使用して、 ServerB が属するドメインのドメイン コントローラーの完全修飾ドメイン名 (FQDN) を指定します。
# For ServerC in Contoso domain and ServerB in other domain
$ServerB = Get-ADComputer -Identity ServerB -Server dc1.alpineskihouse.com
$ServerC = Get-ADComputer -Identity ServerC
Set-ADComputer -Identity $ServerC -PrincipalsAllowedToDelegateToAccount $ServerB
ServerC に資格情報を委任する機能を削除するには、ServerC の PrincipalsAllowedToDelegateToAccount パラメーターの値に $null
を設定します。
Set-ADComputer -Identity $ServerC -PrincipalsAllowedToDelegateToAccount $null
リソースに基づく Kerberos の制約付き委任についての情報
- Kerberos 認証の新機能
- Windows Server 2012 による Kerberos の制約付き委任の処理方法、第 1 部
- Windows Server 2012 による Kerberos の制約付き委任の処理方法、第 2 部
- 統合 Windows 認証での Azure Active Directory アプリケーション プロキシ展開に対する Kerberos の制約付き委任の概要
- [MS-ADA2 Active Directory スキーマ属性 M2.210 属性 msDS-AllowedToActOnBehalfOfOtherIdentity]MS-ADA2
- [MS-SFU Kerberos プロトコル拡張機能: Service for User and Constrained Delegation Protocol 1.3.2 S4U2proxy]MS-SFU
- PrincipalsAllowedToDelegateToAccount を使用した制約付き委任を使用しないリモート管理
Kerberos の委任 (無制限)
Kerberos の制約のない委任を使用して、2 番目のホップを作成することもできます。 すべての Kerberos シナリオと同様に、資格情報は格納されません。 このメソッドでは、WinRM の 2 番目のホップはサポートされていません。
警告
この方法では、委任された資格情報がどこで使われるかは制御されません。 CredSSP よりも安全性が低くなります。 このメソッドは、テスト シナリオにのみ使用してください。
Just Enough Administration (JEA)
JEA では、PowerShell セッションの間に管理者が実行できるコマンドを制限できます。 これを使って、次ホップの問題を解決できます。
JEA については、「Just Enough Administration」をご覧ください。
長所
- 仮想アカウントを使う場合にパスワードの管理が不要です。
短所
- WMF 5.0 以降が必要です。
- すべての中間サーバー (ServerB) の構成が必要です。
RunAs を使用する PSSessionConfiguration
ServerB にセッション構成を作成し、その RunAsCredential パラメーターを設定できます。
PSSessionConfiguration と RunAs を使って次ホップの問題を解決する方法については、PowerShell をリモートから使用する場合のマルチホップの別の解決策に関するページをご覧ください。
長所
- WMF 3.0 以降のすべてのサーバーで機能します。
短所
- すべての中間サーバー (ServerB) で PSSessionConfiguration と RunAs を構成する必要があります。
- ドメインの RunAs アカウントを使うときは、パスワードの管理が必要です。
Invoke-Command スクリプト ブロックの内部で資格情報を渡す
Invoke-Command コマンドレットを呼び出すときに ScriptBlock パラメーターの内部で資格情報を渡すことができます。
長所
- 特別なサーバー構成は必要ありません。
- WMF 2.0 以降を実行する任意のサーバーで動作します。
短所
- 面倒なコード技法が必要です。
- WMF 2.0 を実行している場合は、リモート セッションに引数を渡すために異なる構文が必要です。
例
次の例は、スクリプト ブロックで資格情報を渡す方法を示しています。
# This works without delegation, passing fresh creds
# Note $Using:Cred in nested request
$cred = Get-Credential Contoso\Administrator
Invoke-Command -ComputerName ServerB -Credential $cred -ScriptBlock {
hostname
Invoke-Command -ComputerName ServerC -Credential $Using:cred -ScriptBlock {hostname}
}