PAC在Kerberos认证协议中的作用(一)

今天和大家来聊一聊Kerberos认证协议以及PAC在Kerberos中所起到的作用。

首先什么是Kerberos认证协议呢? 

Kerberos是一套网络认证服务协议, 他是由RFC1510定义, 提供了一种在开放的非安全网络中认证识别用户身份信息的方法。

在Kerberos V5验证协议中,其验证过程包含六个消息(其中五个是必须的,一个是可选的)。如图所示,它们分别是KRB_AS_REQ,KRB_AS_REP,KRB_TGS_REQ,KRB_TGS_REP,KRB_AP_REQ和KRB_AP_REP。其中KRB_AP_REP为可选消息。

整个验证过程由三个类型的消息交换组成,验证服务交换,票据授予服务交换和客户端/服务端交换。验证服务交换包括KRB_AS_REQ和KRB_AS_REP消息,该验证服务交换在用户登录,或者TGT(票据授予票)过期时发生。票据授予服务交换包括KRB_TGS_REQ和KRB_TGS_REP消息。客户端/服务端交换包括KRB_AP_REQ和KRB_AP_REP消息。

详细的验证过程如下:

  1. KRB_AS_REQ:用户向KDC(密匙分发中心)的验证服务申请TGT。消息包括用户主体名称,域名和预认证信息。该预认证信息是用用户密码推导出来的密匙加密的。
  2. KRB_AS_REP:验证服务会生成TGT,并生成一个会话密匙(Session Key)。KDC在收到KRB_AS_REQ消息之后,将从数据库中获得该用户的密匙,然后利用该密匙解密预认证信息,验证用户。验证通过后,会生成TGT和会话密匙。该会话密匙又称登录会话密匙,是用户与KDC共享的。TGT中包括登录会话密匙和PAC(特权属性证书)。TGT用KDC的密匙加密,登录会话密匙用用户密匙加密,最后返回给用户。
  3. KRB_TGS_REQ:用户通过提供TGT,认证器和服务主体名向TGS申请服务票(service
    ticket)。用户收到KRB_AS_REP消息之后,用用户密匙解密登录会话密匙,保存登录会话密匙在证书缓存中。用户准备一个用登录会话密匙加密的认证器(authenticator),连同TGT和服务主体名发送给KDC。
  4. KRB_TGS_REP:TGS生成服务票。KDC收到KRB_TGS_REQ消息之后,首先用自己的密匙将TGT解密,获得登录会话密匙,然后用它解密认证器,验证用户的有效性。当用户通过验证之后,KDC会生成一个用户与服务共享的会话密匙和一个服务票。服务票中包含用户与服务共享的会话密匙的副本和用户PAC,该票用服务的密匙加密。而会话密匙用登录会话密匙加密。KDC最后将两者返回用户。
  5. KRB_AP_REQ:用户将服务票和新的认证器发给服务端,申请访问。用户在收到KRB_TGS_REP消息之后,用登录会话密匙解密用户与服务共享的会话密匙,并将该会话密匙保存在证书缓存中。然后,用户准备一个用会话密匙加密的认证器,连同服务票和一些标志位发送给服务端。
  6. KRB_AP_REP:可选,当用户希望验证提供服务的服务端时,服务端返回该消息。服务端收到KRB_AP_REQ消息之后,会用服务的密匙解密服务票,获得会话密匙,然后利用会话密匙解密认证器获得时间戳,最后验证用户。用户验证通过之后,服务端会生成访问令牌。同时,服务端会检查相互验证标志位是否置位,假如置位,则会利用从认证器中获得的时间戳生成一个新的认证器,然后用会话密匙给认证器加密,最后返回给用户。
  7. 用户收到KRB_AP_REP消息之后,会用会话密匙解密认证器,验证服务的正确性。

 那什么又是PAC呢?PAC在Kerberos认证中如何工作呢?

通过以上的描述,我们看到了RFC1510中规定的标准的Kerberos认证及授权过程, 而微软在自己的产品中所实现的Kerberos工作流程与之则有所不同,其区别的关键就在于,KDC所返回的KRB_AS_REP中将包含一组PAC的信息。

PAC的全称是Privilege Attribute Certificate(特权属性证书), 其中所包含的是各种授权信息, 例如用户所属的用户组, 用户所具有的权限等。

正如上文所述,当用户与KDC之间完成了认证过程之后, 用户需要访问服务器所提供的某项服务时, 服务器为了判断用户是否具有合法的权限必须通过将用户的用户名传递给KDC, KDC通过得到的用户名查询用户的用户组信息, 用户权限等, 进而返回给服务器, 服务器再将此信息与用户所索取的资源的ACL进行比较, 最后决定是否给用户提供相应的服务。

在Windows的Kerberos实现中, 默认情况下,KRB_AS_REP信息中将包含一组PAC信息, 也就是说, 用户所得到的TGT(TicketGranting Ticket)会包含用户的授权信息。用户再用包含有授权信息的TGT去申请相应的Service Ticket,KDC在收到这个KBR_AP_REQ请求的时候, 将TGT里的PAC信息解析出来, 加入到Service Ticket里返回。接下来, 当用户向服务器程序提交KRB_AP_REQ消息时, 服务器程序则将其中所包含的PAC信息传送给操作系统得到一个访问令牌, 并且同时将这个PAC的数字签名以KRB_VERIFY_PAC的消息传输给KDC, KDC再将验证这个PAC的数字签名的结果以RPC返回码的形式告诉服务器, 服务器就可以根据这个结果判断PAC数据的真实性和完整性,并做出最后对KRB_AP_REQ的判断。

具体的过程如下图所示:

这样做的好处就是在以后对资源的访问中, 服务端再接收到客户的请求的时候不再需要借助KDC的帮助提供完整的授权信息来完成对用户权限的判断, 而只需要根据请求中所包含的PAC信息直接与本地资源的ACL相比较做出裁决。

那PAC的存在究竟给我们的验证过程带来了哪些优点,抑或是缺点呢?

正如上文所提到的那样, PAC的引入其实带来了很多的优点。客户端在访问网络资源的时候服务端不再需要向KDC查询授权信息, 而是直接在本地进行PAC信息与ACL的比较。从而节约了网络资源。如下图所示, 在没有PAC的情况下,Server与KDC之间必须进行用户授权信息的查询与返回 :

 

当引入PAC之后则变成了如下图所示的情况:

但是,PAC的引入并不是百利而无一害的,PAC在用户的认证阶段引入会导致认证耗时过长。这个问题是因为相较其他的实现,Windows
Kerberos客户端会通过RPC调用KDC上的函数来验证PAC信息,这时候用户会观察到在服务器端与KDC之间的RPC包流量的增加。而另一方面, 由于PAC是微软特有的一个特性,所以启用了PAC的域中将不支持装有其他操作系统的服务器, 制约了域配置的灵活性。

看到了以上缺点,那我们有没有办法不要让服务器程序进行PAC验证以加快验证过程呢?答案是可以的,以下就提供在服务器端关闭PAC验证服务的方法:

  1. 启动注册表编辑器regedit.exe
  2. 找到以下子键:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters
  3. 添加一个ValidateKdcPacSignature的键值(DWORD类型), 如果将这个设置为0, 则服务程序就不会进行PAC认证, 而如果将这个键值设置为1, 则相反。
  4. 但是对于这个注册表键值,有以下几点注意事项:
  • 注意:如果服务端并非一个服务程序,而是一个普通应用程序,它将不受以上注册表的影响,而总是进行PAC认证。
  • 注意:如果服务端并非一个程序,而是一个驱动,其认证过程在系统内核内完成,它将不受以上注册表的影响,而永不进行PAC认证。
  • 注意:使用以上注册表项,需要Windows Server 2003 SP2或更新的操作系统。
  • 注意:在运行Windows Server 2008或更新操作系统的服务器上,该注册表项的值缺省为0。

对于单个用户如何指定是否需要进行PAC验证呢?我们可以通过以下方法来控制:

  1. 打开用户属性

2. 在Account选项卡中把Do not require Kerberos Preauthentication选中,则此用户就不需要进行PAC验证了。

所以,对于PAC的使用还是由用户的应用特性来决定,如果需要减少服务器和KDC之间的认证信息流量从而使得用户能够更快的访问到所需要的资源,我们可以启用PAC;而另一方面,如果用户所属的组非常多,PAC信息本身所占用的容量会变得非常大,使得在做PAC认证的时候,服务器和KDC之间的数据通信变的异常频繁,用户可能因此在认证阶段耗时过长,那么我们就可以考虑禁用PAC来加快验证速度。

以上我们简单介绍了PAC在Kerberos验证中的作用以及它的优点和缺点,希望对大家会有所帮助,在接下来的AD部分的博客中,我们还会推出关于PAC的更加深入的讨论,尽请期待。

 谢谢,

屈贝伟 | 企业平台支持部AD技术工程师 | 微软亚太区全球技术支持中心

 

 

本博文仅供参考,微软公司对其内容不作任何责任担保或权利赋予。