“第二跃点问题”是指如下所示的情况:
- 你已登录到 ServerA。
- 在 ServerA 中,启动远程 PowerShell 会话以连接到 ServerB。
- 通过 PowerShell 远程处理会话在 ServerB 上运行的命令会尝试访问 ServerC 上的资源。
- 拒绝访问 ServerC 上的资源,因为用于创建 PowerShell 远程处理会话的凭据不会从 ServerB 传递到 ServerC。
有多种方法可以解决此问题。 下表列出了按首选项顺序的方法。
配置 | 注释 |
---|---|
CredSSP | 平衡易用性和安全性 |
基于资源的 Kerberos 约束委派 | 使用更简单的配置提高安全性 |
Kerberos 约束委派 | 高安全性,但需要域管理员 |
Kerberos 委派(不受约束) | 不推荐 |
刚好政府 (JEA) | 可以提供最佳安全性,但需要更详细的配置 |
使用 RunAs 的 PSSessionConfiguration | 配置更简单,但需要凭据管理 |
在 Invoke-Command 脚本块内传递凭据 |
最简单的使用,但必须提供凭据 |
CredSSP
可以使用 凭据安全支持提供程序(CredSSP) 进行身份验证。 CredSSP 在远程服务器(ServerB)上缓存凭据,因此使用它可打开凭据盗窃攻击。 如果远程计算机被攻破,攻击者将有权访问用户的凭据。 默认情况下,CredSSP 在客户端和服务器计算机上都处于禁用状态。 应该仅在最受信任的环境中启用 CredSSP。 例如,连接到域控制器的域管理员是高度信任的。
有关使用 CredSSP 进行 PowerShell 远程处理时的安全问题的详细信息,请参阅 意外破坏:注意 CredSSP。
有关凭据盗窃攻击的详细信息,请参阅 缓解哈希(PtH)攻击和其他凭据盗窃。
有关如何启用和使用 CredSSP 进行 PowerShell 远程处理的示例,请参阅 使用 CredSSP 启用 PowerShell“第二跃点”功能。
优点
- 它适用于具有 Windows Server 2008 或更高版本的所有服务器。
缺点
- 存在安全漏洞。
- 需要配置客户端角色和服务器角色。
- 不适用于受保护的用户组。 有关详细信息,请参阅 受保护的用户安全组。
Kerberos 约束委派
可以使用旧式约束委派(而不是基于资源)来生成第二个跃点。 使用选项“使用任何身份验证协议”配置 Kerberos 约束委派以允许协议转换。
优点
- 无需特殊编码
- 凭据不存储。
缺点
- 不支持 WinRM 的第二个跃点。
- 需要域管理员访问权限才能配置。
- 必须在远程服务器的 Active Directory 对象(ServerB)上配置。
- 限制为一个域。 无法跨域或林。
- 需要有权更新对象和服务主体名称(SPN)。
- ServerB 可以代表用户获取 ServerC 的 Kerberos 票证,而无需用户干预。
注释
具有帐户的 Active Directory 帐户很敏感,无法委派 属性集。 有关详细信息,请参阅 安全焦点:分析特权帐户 和 Kerberos 身份验证工具和设置的“帐户敏感且无法委派”。
基于资源的 Kerberos 约束委派
使用基于资源的 Kerberos 约束委派(在 Windows Server 2012 中引入),可以在资源所在的服务器对象上配置凭据委派。 在上述第二个跃点方案中,将 ServerC 配置为从中指定接受委派凭据的位置。
优点
- 凭据不存储。
- 使用 PowerShell cmdlet 进行配置。 无需特殊编码。
- 不需要域管理员访问权限才能配置。
- 跨域和林工作。
缺点
- 需要 Windows Server 2012 或更高版本。
- 不支持 WinRM 的第二个跃点。
- 需要有权更新对象和服务主体名称(SPN)。
注释
具有帐户的 Active Directory 帐户很敏感,无法委派 属性集。 有关详细信息,请参阅 安全焦点:分析特权帐户 和 Kerberos 身份验证工具和设置的“帐户敏感且无法委派”。
示例:
让我们看看一个 PowerShell 示例,该示例在 ServerC 上配置基于资源的约束委派以允许来自 ServerB 的委派凭据。 此示例假定所有服务器都在运行受支持的 Windows Server 版本,并且每个受信任域至少有一个 Windows 域控制器。
在配置约束委派之前,必须添加 RSAT-AD-PowerShell
该功能才能安装 Active Directory PowerShell 模块,然后将该模块导入到会话中:
Add-WindowsFeature RSAT-AD-PowerShell
Import-Module ActiveDirectory
Get-Command -ParameterName PrincipalsAllowedToDelegateToAccount
多个可用的 cmdlet 现在具有 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,其中包含一个访问控制列表(ACL),该列表指定哪些帐户有权将凭据委托给关联帐户(在本示例中,它将是 ServerA 的计算机帐户)。
现在,让我们设置用于表示服务器的变量:
# Set up variables for reuse
$ServerA = $Env:COMPUTERNAME
$ServerB = Get-ADComputer -Identity ServerB
$ServerC = Get-ADComputer -Identity ServerC
WinRM(因此 PowerShell 远程处理)默认作为计算机帐户运行。 可以通过查看服务的 StartName 属性 winrm
来查看此内容:
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 分钟以清除缓存。
清除缓存后,可以通过 ServerB 将代码从 ServerA 成功运行到 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)
}
在此示例中,范围 Using:
修饰符用于使 $ServerC
变量对 ServerB 可见。 有关 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
如果要跨域创建第二个跃点,请使用 服务器 参数指定 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 身份验证进行Microsoft Entra 应用程序代理部署的 Kerberos 约束委派
- [MS-ADA2 Active Directory 架构属性 M2.210 Attribute msDS-AllowedToActOnBehalfOfOtherIdentity]MS-ADA2
- [MS-SFU Kerberos 协议扩展:用户和约束委派协议 1.3.2 S4U2proxy 的服务]MS-SFU
- 使用 PrincipalsAllowedToDelegateToAccount 进行不受约束的远程管理
Kerberos 委派(不受约束)
还可以使用 Kerberos 不受约束的委派来生成第二个跃点。 与所有 Kerberos 方案一样,不会存储凭据。 此方法不支持 WinRM 的第二个跃点。
警告
此方法不控制使用委派凭据的位置。 它比 CredSSP 不安全。 此方法只应用于测试方案。
刚好政府 (JEA)
JEA 允许限制管理员可以在 PowerShell 会话期间运行的命令。 它可用于解决第二个跃点问题。
有关 JEA 的信息,请参阅 Just Enough Administration。
优点
- 使用虚拟帐户时没有密码维护。
缺点
- 需要 WMF 5.0 或更高版本。
- 要求在每个中间服务器上配置(ServerB)。
使用 RunAs 的 PSSessionConfiguration
可以在 ServerB 上创建会话配置并设置其 RunAsCredential 参数。
有关使用 PSSessionConfiguration 和 RunAs 解决第二跃点问题的信息,请参阅 多跃点 PowerShell 远程处理的另一个解决方案。
优点
- 使用 WMF 3.0 或更高版本的任何服务器。
缺点
- 要求在每个中间服务器上配置 PSSessionConfiguration 和 RunAs。
- 使用域 运行方式 帐户时需要密码维护
在 Invoke-Command 脚本块内传递凭据
可以在对 Invoke-Command cmdlet 的调用的 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}
}