Kerberos令牌大小及其增长问题

时间:2020-01-09 10:46:40  来源:igfitidea点击:

最近,当某些用户由于Kerberos令牌过大而无法在某些域服务上进行身份验证时,我遇到了一个非常有趣的问题。在本文中,我们将尝试考虑构建Kerberos令牌的特殊性,用户如何定义其大小以及如何扩展缓冲区以存储它。

在我们的案例中,问题以这种方式表现出来。有些用户无法访问某些已部署的服务。特别是,尝试连接到RDS服务器场时出现错误(访问被拒绝错误)。

在远程桌面服务器的日志中,已记录错误事件ID 6:

kerberos SSPI软件包生成了大小为21043字节的输出令牌,该令牌太大而无法容纳进程ID 4提供的大小为12000字节的令牌缓冲区。输出SSPI令牌太大可能是用户user @的结果域是大量组的成员。建议尽量减少用户所属的组数。如果无法通过减少此用户的组成员身份来解决此问题,请与系统管理员联系以增加最大令牌大小,即通过以下注册表值在机器范围内配置的最大令牌大小:HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters\MaxTokenSize。

尝试连接到SQL Server时,事件日志中出现以下错误:

事件ID 40960

安全系统检测到服务器XXXXXX的身份验证错误。身份验证协议Kerberos的失败代码为{Buffer Too Small}缓冲区太小,无法包含该条目。尚未将任何信息写入缓冲区。(0xc0000023)。

检查访问这些资源的权限没有显示任何问题。在进一步检查期间,发现了以下依赖关系:遇到问题的所有用户都是许多Active Directory安全组(包括子组在内的200个以上)的成员。因此,我们得出的结论是,由于用于验证用户的Kerberos票证的尺寸过大,导致出现了问题。

Kerberos令牌大小

Kerberos令牌的大小取决于以下因素:

  • 用户所属的Active Directory安全组(包括子组)的数量(令牌中不包含分发组)
  • SIDHistoryNote的使用。当用户在Active Directory域之间迁移并且使用SIDHistory访问旧域资源时,票证过大的问题经常发生
  • 所使用的身份验证类型(通常的密码或者多重因素,例如智能卡)
  • 该帐户是否受信任进行委派

Kerberos使用缓冲区存储身份验证数据,并使用Kerberos将其大小传输到应用程序。系统参数" MaxTokenSize"定义缓冲区的大小。缓冲区大小很重要,因为某些协议(例如RPC或者HTTP)使用它来设置用于身份验证的内存块。如果用户认证数据的大小大于MaxTokenSize中的值,则认证失败。这可以解释访问IIS时的身份验证错误,同时保留对网络资源的文件访问。

默认情况下,Kerberos缓冲区的大小(MaxTokenSize)为

  • Windows 7和Windows Server 2008R2中为12 KB
  • 在Windows 8和Windows Server 2012中扩展为48 KB

因此,如果用户是许多组的成员,则所有组描述都不适合12 KB,并且在尝试访问某些资源时,会出现身份验证错误。

提示。用户可以加入的AD组的数量有严格的限制。此限制是1015组。如果有更多组,则用户登录时会发生以下错误:由于以下错误,系统无法登录我们:登录尝试期间,用户安全上下文累积了太多的安全ID。请重试或者咨询系统管理员

如何获取Kerberos票证的当前大小

Windows没有便捷的内置工具,该工具无法获取特定用户的Kerberos令牌大小。

若要了解当前票证的大小,请使用第三方Powershell脚本CheckMaxTokenSize.ps1(由Tim Springston Microsoft提供)。该脚本允许获取所选用户的令牌的当前大小,包含令牌的安全组的数量,用户SIDHistory中存储的SID的数量以及是否信任帐户进行委派。

要使用此脚本,请通过上面的链接下载该脚本,然后另存为CheckMaxTokenSize.ps1.

禁用脚本检查:

Set-ExecutionPolicy RemoteSigned

转到包含脚本的目录:

Cd c:\install\ps

并获取用户jsmith的Kerberos票证的大小:

.\CheckMaxTokenSize.ps1 -Principals 'jsmith' -OSEmulation $true -Details $true

该脚本提示我们指定必须为其计算用户令牌大小的环境。有两种变体:

Windows 7/Windows Server 2008 R2或者更早版本为" 1"(令牌大小为12 KB)

Windows 8/Windows Server 2012或者更高版本为" 4"(令牌大小为48 KB)

按1,然后按ENTER。在一段时间(3-4分钟)中,脚本将返回以下信息:

用户jsmith的令牌详细信息\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*用户的域为CORP。估计的令牌总大小为22648. 对于访问DC和可分配的资源,估计的令牌委托总大小为45269有效的MaxTokenSize值为:12000检测到问题。令牌太大,无法进行一致的授权。更改每KB最大大小http://support.microsoft.com/kb/327825,并考虑减少直接和传递组成员身份。\* jsmith的令牌详细信息\*令牌中有957个组。用户SIDHistory中有SID。用户组SIDHistory属性中有248个SID。用户和用户所属的组共有248个SIDH历史记录。 1088是域全局范围安全组。 37个是域本地安全组。 86是用户域内部的通用安全组。 0是用户域外部的通用安全组。 > C:\Windows\temp\TokenSizeDetails.txt的输出文件中包含的组详细信息SIDHC:\Windows\temp\TokenSizeDetails.txt的输出文件中包含的组详细信息

因此,我们已定义用户jsmith是957个域安全组的成员,其Kerberos票证的大小为22648,几乎是Windows 7/Windows Server 2008 R中标准Kerberos令牌大小的2倍。

因此,要解决身份验证问题,我们必须减小用户令牌的大小,或者扩展所有出现Kerberos身份验证问题的服务器系统中的缓冲区大小。

如何减少用户Kerberos令牌

如果可能,尝试通过以下方法减小用户Kerberos令牌的大小:

  • 减少用户所属的组的数量。 可以使用Windows Server 2012动态访问控制中出现的控制对文件资源的访问的新机制来完成此操作
  • 清除SID历史记录
  • 拒绝信任帐户进行委派(极大地减少了令牌的大小)

如何增加Kerberos令牌的大小

如果我们无法减小用户Kerberos票证的大小,则可以增加它的缓冲区大小。为此,有一个特殊的注册表设置" MaxTokenSize"。

Microsoft不建议将MaxTokenSize设置为大于64 KB。在一般情况下,建议将限制扩展到48 KB(Windows 8/2012的限制)。要增加缓冲区:

  • 打开注册表编辑器,然后转到" HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters"。
  • 创建一个新的DWORD(" 32位"值)参数,其名称为" MaxTokenSize"
  • 指定最大缓冲区大小的必要值(我们指定了48,000,因为用户令牌的大小不超过该值)
  • 重新启动系统。

这必须在发生身份验证问题的所有服务器系统中完成。

如果IIS站点中出现身份验证问题,则还需要将HTTP标头的大小扩展到64 KB(0000ffff)。默认情况下,最大标头大小为16 KB。为此,我们必须对IIS服务器上的注册表进行以下更改(也需要重新启动):

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\HTTP\Parameters\MaxFieldLength
DWORD:0000ffff
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\HTTP\Parameters\MaxRequestBytes
DWORD:0000ffff

在Windows 8和Windows Server 2012中,出现了一个新策略,该策略允许设置最大MaxTokenSize"设置最大Kerberos SSPI上下文令牌缓冲区大小"。它位于"计算机配置"->"策略"->"管理模板"->"系统"->" Kerberos"中。

此外,还有另一个有用的策略"警告大型Kerberos票证",该策略允许配置在系统日志中显示票证过大的通知。

启用该策略后,如果超出票证的阈值大小,则将使用以下文本消息将"事件31"写入日志:

为帐户AccountName @ DomainName发行了服务ldap/DC Name/DomainName的票证。该票证的加密部分的大小为22648字节,接近或者大于配置的票证大小阈值(12000字节)。如果客户端或者服务器应用程序分配由接近阈值的值限制的SSPI令牌缓冲区,则此票证或者由此票证发行的任何其他票证都可能导致身份验证失败。

票证的大小在很大程度上取决于其携带的授权数据的大小。授权数据的大小取决于帐户所属的组,为其设置帐户的声明数据以及在资源域中解析的资源组。