Kerberos 是一个网络验证协议,通过使用密钥来为 client/server 应用提供高强度的安全校验。一个开源的实现是由 Massachusetts Institute of Technology 实现。Kerberos 也在很多商业产品中被使用。

Kerberos 使用 UDP,默认使用 88 端口

在 Hadoop 生态中涉及到的安全问题可以大致归纳为两类,Authentication 和 Authorization:

  • Authentication 认证用户身份,也就是证明 A 是 A 的问题
  • Authorization 则是权限控制,A 用户能够做什么操作

Kerberos 解决的问题就是证明 A 是 A 的问题,也就是 Authentication。

Kerberos 中的概念

principle ,可以理解成认证主体,client 和 server 的名字

realm 是空间, principle 需要在 realm 下

password, 用户密码,可以存放在 keytab 文件中

credential 凭据

Long-term Key ,长期保持不变的 key,比如密码,可能长年不变。Long-term Key 在原则上不应当在网络传输,因为一旦被截获,破解者有足够的时间来破解该密码

Master Key ,而一般情况下对于一个账户,密码仅限于该账户的所有者知道,这种情况下,通常将密码 Hash,得到一个 hash code,一般将这样的 hash code 叫做 Master key。因为 Hash 算法不可逆,同时能够保证密码和 Master Key 一一对应,既保证了密码的安全性,同时保证了 Master Key 和密码本身可以证明身份。

Short-term Key or Session Key, 因为 Long-term Key 加密的数据包不能用于网络传输,所以出现了 Short-term Key 用来加密需要网络传输的数据,这一类型的 Key 只在短时间内有效,即使被加密的数据被截获,等将 Key 解密出来时,Key 也早已经过期

Kerberos 中有三种角色:

  • KDC:负责分发密钥的密钥分配中心,在 Client 和 Server 之间担任共同信任的角色
  • Client:需要使用 kerbores 服务的客户端
  • Service:提供具体服务的服务端

认证原理

KDC 分发 Session Key 的过程

Client 如果要获取 Server 资源,先得通过 Server 认证,也就是 Client 需要向 Server 提供从 KDC 获取的带有 Server Master Key 加密的 Session Ticket(Session Key + Client Info). Session Ticket 是 Client 访问 Server 的一张门票,而这张门票需要从合法的 Ticket 发行机构(KDC)获取。同时这张票具有防伪标识(被 Server Master Key 加密过)。

简化一下上面描述的过程,当 Client 要获取 Server 资源时,首先要向 KDC 发送 Session Key 的申请,内容就是,我是某某 Client,我需要访问某某 Server 的 Session Key。KDC 在收到请求后,生成一个 Session Key,为保证 Session Key 仅仅限于发送请求的 Client 和它希望访问的 Server,KDC 会将这个 Session Key 生成两个拷贝,分别被 Client 和 Server 使用,并从数据库中提取 Client 和 Server 的 Master Key 对这两个拷贝进行对称加密,对于 Server 的拷贝还会将 Client 的信息保存到 Session Key。KDC 现在有两个加密过的 Session Key,Kerberos 将这两个拷贝一并发送到 Client。

这边会产生一些问题,比如 KDC 并没有验证这个请求的 Client 是否真的是他自己?但仔细想一下,假如 Client B 假装自己的是 A,那么会得到 Client A 和 Server 的 Session Key,而这时 B 并不知道 A 的 Master Key,所以获得的 Session Key 并不能拿来访问 Server。

Kerberos client access server

认证过程 Authenticator

经过 KDC 分发 Session Key,Client 获得了两个有效信息,一个通过自己的 Master Key 加密的 Session Key,一个被 Server 的 Master Key 加密的数据包(包含 Session Key 和 Client 的信息)

再此基础上,Server 如何认证 Client。首先 Client 通过自己的 Master Key 对 KDC 分发的 Session Key 解密从而获得 Session Key,随后创建 Authenticator(Client Info + Timestamp) 并用 Session Key 对其加密,最后连同从 KDC 获取的被 Server Master Key 加密过得数据包(Client Info + Session Key)一并发送到 Server 段。把通过 Server Master Key 加密过的数据包称为 Session Ticket。

当 Server 接受到两组数据后,用自己的 Master Key 对 Session Ticket 解密,得到 Session Key。然后用该 Session Key 解密 Authenticator,比较 Authenticator 中的 Client Info 和 Session Ticket 中的 Client Info 从而实现对 Client 的认证。Server 需要检查:

  • Authenticator 中 Timestamp 是否在当前时间前后 5 分钟内
  • 检查 内容是否一致

Kerberos client server

双向认证

Kerberos 的优势在于能够提供双向认证,Server 可以对 Client 认证,Client 也能够对 Server 进行认证。

如果 Client 需要对访问的 Server 认证,会在向 Server 发送的 Credentials 中设置是否需要认证的 Flag,Server 在对 Client 认证成功后,会把 Authenticator 中 Timestamp 提出来,通过 Session Key 加密发送到 Client,Client 接受并使用 Session Key 解密后,确认 Timestamp 是否一致,从而来判断 Server 是 Client 确定要访问的。

完整认证流程

上面提及的认证流程每次 Client 都要使用自己的 Master Key,为了解决这个问题,Kerberos 引入新角色:Ticket Granting Service(TGS),给 Client 提供用于连接 Server 的票据。这样 Kerberos 就有四个角色。完整的认证流程:

  • Client 向 KDC 发出请求,希望和 TGS 通信,请求内容分别为自身的 principle 和 TGS 的 principle
  • KDC 收到请求后,通过 Client 和 TGS 的 Master Key 生成两份 Session Key,一份用 Client Master Key 加密的 SKDC-Client,一份 KDC master Key 加密的 TGT
  • 客户端用自己的 Master Key 解开 Session Key,然后生成 Authenticator(Client Info + Timestamp),并给 TGS 发出请求。Client 会缓存 Session 和 TGT,有了 Session Key 和 TGT 之后,Client 就不在需要自己的 Master Key,此后 Client 可以使用 SKDC-Client 向 KDC 申请用来访问 Server 的 Ticker
  • TGS 收到 Client 的请求后,用自己的 Master Key 解密 Session Ticket,得到 Session Key,然后用 Session Key 解密 Authenticator 得到 Client Info 和 Timestamp ,校验客户端。通过认证之后,TGS 生成一个 Client 和 Server 的 Session Key,而在此处,TGS 将不再使用 Client 的 Master Key 进行对称加密,而是使用 Client 和 TGS 之间的 Session Key 加密

kerberos client tgt

Ticker 是和具体 Server 相关,而 TGT 则是和具体 Server 无关的,Client 可以使用 TGT 从 KDC 获得不同 Server 的 Ticket。

kerberos client kdc tgt

reference