近日给公司搭建KDC认证服务,简单总结了一下Kerberos协议,便于理解。个人习惯,把一个东西条理清晰地表述出来,更容易掌握。
一、背景
分布式环境下,传统端到端加密框架的局限性:
- 各节点两两之间需要互相持有密钥
- 密钥长期不更新,一旦密钥被解出就相当于明文通信
- 更新密钥需要走网络交换,有泄露密钥的风险
- 更新信任关系需要更新所有节点
- 认证消息包可能被截获
使用Kerberos协议的好处:
- 可以实现范围内的节点互信
- 更新密钥不通过网络交换
- 各节点之间的信任关系基于节点与KDC共享各自的密钥
- 各节点可以缓存通用票据,在票据失效之前可用于访问其他节点(单点登录)
- 认证消息带时间戳,避免被伪造
Kerberos协议的局限性:
- 各节点与KDC之间需要相对同步的时间(最大时间相位差的默认值为5分钟)
二、协议分析
认证过程示意图
网络数据包内容
KDC保障以下场景的节点互信:
- 客户端和服务端之间互信(例如hbase/hdfs的客户端和服务端)
- 服务端节点之间互信(hbase/hdfs的服务端节点)
本文将互信定义为使用同一份密钥来通信。这里将通信请求方定义为client,被请求方定义为server。client定期从KDC请求到一份新的密钥,发往server,server确认密钥可信之后使用这份密钥与client通信。
获取TGT和TGS Session Key
Client明文[1] 给KDC的Authentication Server(简称AS)发送自己的用户名(Client’s principal)、时间戳、申请ticket时长
AS Reply用Client和KDC共享的密钥(紫色,保障返回给真的Client)加密,内容包含:
- Client和TGS通信用的TGS Session Key(黄色)
- ticket有效期
- TGT(使用KDC的krbtgt Key(红色)密钥加密,Client不可解,包含Client信息与TGS Session Key(黄色),保障AS和TGS同属于一个KDC集群,可以是不同机器)
这里TGT的意义是AS给Client和TGS分发的临时Ticket,假的Client无法解开来修改里面的Client信息,假的TGS没有krbtgt Key也无法解密TGT。只有真正的Client和TGS可以用TGS Session Key加密通信内容。
获取TGS和Service Session Key
Client将自己的信息和需要访问的服务、连同TGT一起打包发送给KDC的Ticket Granting Server(简称TGS),数据包内容为:
- Client用户名和时间戳(用TGS Session Key加密,保障Client是真的)
- Client想访问的服务名(service’s principal)
- 请求的ticket有效期
- TGT(KDC的krbtgt(红色)密钥加密,保障Client是真的)
TGS Reply用TGS Session Key(黄色)加密,内容如下:
- 服务名(service’s principal)
- Client和Server通信用的Service Session Key(粉色)
- Service Ticket有效期
- TGS(即Service Ticket,Client不可解,包含Client信息与Service Session Key,保障返回给真的Client)
使用Service Ticket与Server请求认证
Client用Service Session Key加密Client用户名和时间戳,把它和TGS一起打包发往想要访问的Server,包内容为:
Server先解开TGS,检查Client是否有权限,如果未授权可以直接拒绝访问。否则用TGS里的Service Session Key加密服务名和时间戳返回给Client
Client收到AP Reply,解出服务名,验证是自己想要访问的服务,互信完成。在有效期内使用Service Session Key加密通信内容
注意KDC只是完成了身份认证和密钥分发,不包含ACL和通信内容加密。完整的加密传输还要依赖SASL、GSSAPI、SPNEGO等其他框架
抓包分析
以Wireshark抓的一些数据包为例,来看两次KDC请求的实际内容
蓝色部分是Wireshark尝试用我提供的包含Client、Server密钥的Keytab解出来的内容
可以看到黄色部分的TGT的密钥由KDC保管,无法解密
蓝色部分,TGS Session Key是Client可读,Service Ticket是Server可读。Service Session Key两者都可读
AS_REQ
AS_REP
TGS_REQ
TGS_REP
可以看到,数据包内容和上面官方介绍基本一致
注意事项
根据如果明文,攻击者可以伪造AS_REQ,拿到TGT进行离线破解获取用户密钥。为了防止AS_REQ攻击,建议打开预认证,详情见 Kerberos概述及常见攻击场景