概要
フォレストの信頼は、Active Directory フォレスト内のリソースが別のフォレストの ID を信頼する方法を提供します。 この信頼は、双方向で構成できます。 信頼されたフォレストは、ユーザー ID のソースです。 信頼するフォレストには、ユーザーが認証するリソースが含まれています。 信頼されたフォレストは、逆の実行を許可することなく、信頼するフォレストに対してユーザーを認証できます。
制約のない Kerberos 委任は、ユーザーが資格情報をサービスに送信して、サービスがユーザーの代わりにリソースにアクセスできるようにするメカニズムです。 制約のない Kerberos 委任を有効にするには、Active Directory 内のサービスのアカウントが委任に対して信頼済みとしてマークされている必要があります。 これにより、ユーザーとサービスが異なるフォレストに属している場合に問題が発生します。 サービス フォレストは、委任を許可する役割を担います。 委任には、ユーザーのフォレストからのユーザーの資格情報が含まれます。
あるフォレストが別のフォレストのアカウントに影響を与えるセキュリティ上の決定を行うことを許可すると、フォレスト間のセキュリティ境界に違反します。 信頼するフォレストを所有する攻撃者は、信頼されたフォレストから ID の TGT の委任を要求し、信頼されたフォレスト内のリソースにアクセスできます。 これは、Kerberos の制約付き委任 (KCD) には適用されません。
Windows Server 2012 Kerberos 完全委任のフォレスト境界の適用が導入されました。 この機能により、信頼ごとに制約のない委任を無効にするポリシーが信頼されたドメインに追加されました。 この機能の既定の設定では、制約のない委任が許可され、安全ではありません。
セキュリティ強化を提供するUpdatesは、次のバージョンのWindows Serverに存在します。
- Windows Server 2019
- Windows Server 2016
- Windows Server 2012 R2
- Windows Server 2012
この機能とセキュリティ強化の変更は、次のバージョンにバックポートされました。
- Windows Server 2008 R2
- Windows Server 2008
これらのセキュリティ更新プログラムは、次の変更を行います。
- 制約のない Kerberos 委任は、5 月 14 日以降の更新プログラムをインストールした後、新しいフォレストと新しい外部信頼で既定で無効になります。
- 制約のない Kerberos 委任は、2019 年 7 月 9 日の更新プログラム以降の更新プログラムをインストールした後、フォレスト (新規と既存の両方) と外部信頼で無効になります。
- 管理者は、5 月以降のバージョンの NETDOM および AD PowerShell モジュールを使用して、制約のない Kerberos 委任を有効にすることができます。
この更新により、フォレストまたは外部信頼間で現在制約のない委任が必要なアプリケーションの互換性の競合が発生する可能性があります。 これは、検疫フラグ (SID フィルタリングとも呼ばれます) が既定で有効になっている外部信頼に特に当てはまります。 具体的には、リストされている信頼の種類に対して制約のない委任を使用するサービスに対する認証要求は、新しいチケットを要求すると失敗します。
リリース日については、「Updates タイムライン」を参照してください。
回避策
Kerberos 完全委任のフォレスト境界の適用機能を持つWindows Serverバージョンでデータとアカウントのセキュリティを提供するには、次のように netdom フラグ EnableTGTDelegation を [いいえ] に設定することで、受信信頼全体に 2019 年 3 月の更新プログラムをインストールした後に TGT 委任をブロックできます。
netdom.exe trust fabrikam.com /domain:contoso.com /EnableTGTDelegation:No
TGT 委任は、2019 年 5 月と 7 月の更新プログラムをそれぞれインストールした後、新規および既存のフォレストと外部信頼でブロックされます。
信頼間で委任を再度有効にし、制約付き委任またはリソース ベースの委任を有効にできるようになるまで元の安全でない構成に戻すには、 EnableTGTDelegation フラグを [はい] に設定します。
TGT 委任を有効にする NETDOM コマンド ラインは次のとおりです。
netdom trust <TrustedDomainName > /domain:<TrustingDomainName > /EnableTgtDelegation:Yes
概念的には、TGT 委任を有効にするための NETDOM 構文を次のように考えることができます。
netdom trust <domain that you are administering> /domain:<domain whose trust NETDOM is modifying> /EnableTgtDelegation:Yes
contoso.com サーバー上の fabrakam.com ユーザーの TGT 委任を有効にする NETDOM 構文は次のとおりです。
netdom.exe trust fabrikam.com /domain:contoso.com /EnableTGTDelegation:Yes
注
- EnableTGTDelegation フラグは、信頼するドメイン (contoso.com など) ごとに信頼されたドメイン (この場合は fabrikam.com) に設定する必要があります。 フラグが設定されると、信頼されたドメインでは TGT を信頼ドメインに委任できなくなります。
- EnableTGTDelegation のセキュリティで保護された状態は [いいえ] です。
- EnableTGTDelegation が手動またはプログラムで [はい ] に設定されている場合、フォレスト間の制約のない委任に依存するアプリケーションまたはサービスは失敗します。EnableTGTDelegation は、2019 年 5 月と 2019 年 7 月の更新プログラムをインストールした後、新規および既存の信頼で既定で NO に設定されます。 このエラーを検出する方法の詳細については、「 制約のない委任に依存するサービスの検索」を参照してください。 この回避策の適用方法に影響する変更のタイムラインについては、「Updates タイムライン」を参照してください。
- NETDOM の詳細については、 Netdom.exe ドキュメントを参照してください。
- 信頼で TGT 委任を有効にする必要がある場合は、クライアント コンピューターで Windows Defender Credential Guard を有効にして、そのリスクを軽減することをお勧めします。 これにより、Windows Defender Credential Guard が有効で実行されているコンピューターからの制約のない委任がすべて禁止されます。
- フォレストまたは外部の信頼があり、どちらかが検疫済みとして構成されている場合、2 つのフラグのセマンティクスが逆であるため、TGT 委任を有効にできません。 検疫ビットは、参加ドメイン間のセキュリティ境界を強化します。 TGT 委任を有効にすると、信頼されたドメインからユーザーの資格情報へのアクセス権を信頼ドメインに付与することで、ドメイン間のセキュリティ境界が消去されます。 両方の方法を使用することはできません。
検疫フラグが現在有効になっている場合は、NETDOM コマンド ライン構文に quarantine:no フラグを追加します。 - EnableTGTDelegation を [はい] に変更した場合は、必要に応じて、発信側および中間呼び出し元の Kerberos チケットを削除します。 削除する関連チケットは、関連する信頼全体にわたるクライアントの紹介 TGT です。 これには、特定の環境での委任ホップの数に応じて、複数のデバイスが含まれる場合があります。
この手順の詳細については、次の Windows IT Pro センターの記事を参照してください。
Windows Defender Credential Guard を使用して派生ドメインの資格情報を保護する
Updates タイムライン
2019 年 3 月 12 日
Kerberos 完全委任のフォレスト境界の適用は、この記事の上部にある [適用対象] セクションに記載されているすべてのサポートされているバージョンのWindows Serverでこの機能を有効にするための更新プログラムとして使用できます。 受信フォレストの信頼に対して機能を設定することをお勧めします。
この更新プログラムにより、 Kerberos 完全委任のフォレスト境界の適用 機能が次のシステムに追加されます。
- Windows Server 2008 R2
- Windows Server 2008
2019 年 5 月 14 日
新しいフォレストと外部信頼に新しい安全な既定の構成を追加する更新プログラムがリリースされました。 信頼間での委任が必要な場合は、2019 年 7 月 9 日の更新プログラムがインストールされる前に 、EnableTGTDelegation フラグを [はい ] に設定する必要があります。 信頼間の委任を必要としない場合は、 EnableTGTDelegation フラグを設定しないでください。 EnableTGTDelegation フラグは、2019 年 7 月 9 日の更新プログラムがインストールされるまで無視され、管理者は、必要に応じて制約のない Kerberos 委任を再度有効にする時間を与えます。
この更新プログラムの一環として、 EnableTGTDelegation フラグは、新しく作成された信頼に対して既定で [いいえ ] に設定されます。 これは、前の動作とは逆です。 管理者は、代わりに、影響を受けるサービスを再構成して、リソースベースの制約付き委任を使用することをお勧めします。
互換性の問題を検出する方法の詳細については、「 制約のない委任に依存するサービスの検索」を参照してください。
2019 年 7 月 9 日
フォレストと外部信頼の受信側で新しい既定の動作を適用する更新プログラムがリリースされました。 一覧表示された信頼の種類に対して制約のない委任を使用するサービスの認証要求は認証されますが、委任は行われます。 委任された操作を実行しようとすると、サービスは失敗します。
軽減策については、「回避策」セクションを参照してください。
制約のない委任に依存するサービスの検索
TGT 委任を許可する受信信頼を持つフォレストをスキャンし、制約のない委任を許可するセキュリティ プリンシパルを見つけるには、スクリプト ファイルで次の PowerShell スクリプトを実行します (例: Get-RiskyServiceAccountsByTrust.ps1 -Collect)。
注
-ScanAll フラグを渡して、TGT 委任を許可しない信頼を検索することもできます。
PowerShell スクリプト
[CmdletBinding()]
Param
(
[switch]$Collect,
[switch]$ScanAll
)
if ($Debug) {
$DebugPreference = 'Continue'
}
else {
$DebugPreference = 'SilentlyContinue'
}
function Get-AdTrustsAtRisk
{
[CmdletBinding()]
Param
(
[string]$Direction = "Inbound",
[switch]$ScanAll
)
if ($ScanAll) {
return get-adtrust -filter {Direction -eq $Direction}
}
else {
return get-adtrust -filter {Direction -eq $Direction -and TGTDelegation -eq $false}
}
}
function Get-ServiceAccountsAtRisk
{
[CmdletBinding()]
Param
(
[string]$DN = (Get-ADDomain).DistinguishedName,
[string]$Server = (Get-ADDomain).Name
)
Write-Debug "Searching $DN via $Server"
$SERVER_TRUST_ACCOUNT = 0x2000
$TRUSTED_FOR_DELEGATION = 0x80000
$TRUSTED_TO_AUTH_FOR_DELEGATION= 0x1000000
$PARTIAL_SECRETS_ACCOUNT = 0x4000000
$bitmask = $TRUSTED_FOR_DELEGATION -bor $TRUSTED_TO_AUTH_FOR_DELEGATION -bor $PARTIAL_SECRETS_ACCOUNT
$filter = @"
(&
(servicePrincipalname=*)
(|
(msDS-AllowedToActOnBehalfOfOtherIdentity=*)
(msDS-AllowedToDelegateTo=*)
(UserAccountControl:1.2.840.113556.1.4.804:=$bitmask)
)
(|
(objectcategory=computer)
(objectcategory=person)
(objectcategory=msDS-GroupManagedServiceAccount)
(objectcategory=msDS-ManagedServiceAccount)
)
)
"@ -replace "[\s\n]", ''
$propertylist = @(
"servicePrincipalname",
"useraccountcontrol",
"samaccountname",
"msDS-AllowedToDelegateTo",
"msDS-AllowedToActOnBehalfOfOtherIdentity"
)
$riskyAccounts = @()
try {
$accounts = Get-ADObject -LDAPFilter $filter -SearchBase $DN -SearchScope Subtree -Properties $propertylist -Server $Server
}
catch {
Write-Warning "Failed to query $Server. Consider investigating seperately. $($_.Exception.Message)"
}
foreach ($account in $accounts) {
$isDC = ($account.useraccountcontrol -band $SERVER_TRUST_ACCOUNT) -ne 0
$fullDelegation = ($account.useraccountcontrol -band $TRUSTED_FOR_DELEGATION) -ne 0
$constrainedDelegation = ($account.'msDS-AllowedToDelegateTo').count -gt 0
$isRODC = ($account.useraccountcontrol -band $PARTIAL_SECRETS_ACCOUNT) -ne 0
$resourceDelegation = $account.'msDS-AllowedToActOnBehalfOfOtherIdentity' -ne $null
$acct = [PSCustomobject] @{
domain = $Server
sAMAccountName = $account.samaccountname
objectClass = $account.objectclass
isDC = $isDC
isRODC = $isRODC
fullDelegation = $fullDelegation
constrainedDelegation = $constrainedDelegation
resourceDelegation = $resourceDelegation
}
if ($fullDelegation) {
$riskyAccounts += $acct
}
}
return $riskyAccounts
}
function Get-RiskyServiceAccountsByTrust
{
[CmdletBinding()]
Param
(
[switch]$ScanAll
)
$riskyAccounts = @()
$trustTypes = $("Inbound", "Bidirectional")
foreach ($type in $trustTypes) {
$riskyTrusts = Get-AdTrustsAtRisk -Direction $type -ScanAll:$ScanAll
foreach ($trust in $riskyTrusts) {
$domain = $null
try {
$domain = Get-AdDomain $trust.Name -ErrorVariable eatError -ErrorAction Ignore
} catch {
write-debug $_.Exception.Message
}
if($eatError -ne $null) {
Write-Warning "Couldn't find domain: $($trust.Name)"
}
if ($domain -ne $null) {
$accts = Get-ServiceAccountsAtRisk -DN $domain.DistinguishedName -Server $domain.DNSRoot
foreach ($acct in $accts) {
Write-Debug "Risky: $($acct.sAMAccountName) in $($acct.domain)"
}
$risky = [PSCustomobject] @{
Domain = $trust.Name
Accounts = $accts
}
$riskyAccounts += $risky
}
}
}
return $riskyAccounts
}
if ($Collect) {
Get-RiskyServiceAccountsByTrust -ScanAll:$ScanAll | Select-Object -expandProperty Accounts | format-table
}
PowerShell スクリプトの出力には、制約のない委任が構成されている実行中のドメインからの受信信頼用に構成されているドメイン内の Active Directory セキュリティ プリンシパルが一覧表示されます。 出力は次の例のようになります。
| ドメイン | sAMAccountName | objectClass |
|---|---|---|
| partner.fabrikam.com | 危険 | user |
| partner.fabrikam.com | labsrv$ | に複製 |
Windows イベントを使用した制約のない委任の検出
Kerberos チケットが発行されると、Active Directory ドメイン コントローラーによって次のセキュリティ イベントがログに記録されます。 イベントには、ターゲット ドメインに関する情報が含まれています。 イベントを使用して、受信信頼全体で制約のない委任が使用されているかどうかを判断できます。
注
信頼されたドメイン名と一致する TargetDomainName 値を含むイベントを確認します。
| イベント ログ | イベント ソース | イベント ID | 詳細 |
|---|---|---|---|
| セキュリティ | Microsoft-Windows-Security-Auditing | 4768 | Kerberos TGT が発行されました。 |
| セキュリティ | Microsoft-Windows-Security-Auditing | 4769 | Kerberos サービス チケットが発行されました。 |
| セキュリティ | Microsoft-Windows-Security-Auditing | 4770 | Kerberos サービス チケットが更新されました。 |
認証エラーのトラブルシューティング
制約のない委任が無効になっている場合、アプリケーションが制約のない委任に依存している場合、アプリケーションでこれらの変更との互換性の問題が発生する可能性があります。 これらのアプリケーションは、リソース ベースの制約付き委任または制約付き委任を使用するように構成する必要があります。 詳細については、「 Kerberos の制約付き委任の概要」を参照してください。
信頼全体のラウンドトリップ認証に依存するアプリケーションは、制約付き委任を使用してサポートされていません。 たとえば、フォレスト A のユーザーがフォレスト B のアプリケーションに対して認証を行い、フォレスト B のアプリケーションがフォレスト A にチケットを委任しようとすると、委任は失敗します。