相信接触过Hadoop生态的同学都听过Kerberos的大名,而且在使用大数据组件的时候我们常会被要求传入keytab文件。KDC,AS,TGS这些术语又到底代表的是Kerberos的哪些组成部分呢?为什么Kerberos会被Hadoop选为身份验证机制呢?那就请大家跟着我一起来学习Kerberos协议,解开这个地狱之门守护犬的原理吧。
"Kerberos is an authentication protocol for trusted hosts on untrusted networks"
Kerberos是用于不受信任网络下受信任主机间的认证协议
-- 摘自官网 https://www.kerberos.org/software/tutorial.html
这句话怎么解读呢?有几个关键字:不受信任网络,受信任主机,认证协议。
Kerberos协议的整个认证过程实现不依赖于主机操作系统的认证,无需基于主机地址的信任,不要求网络上所有主机的物理安全,并假定网络上传送的数据包可以被任意地读取、修改和插入数据。说白了, Kerberos通过传统的加密技术(共享密钥)实现了一种可信任的第三方认证服务。
先来认识一些术语和相关组件。
术语和组件
- Realm 领域 身份验证管理域
- 如果用户、服务共享一个secret(password/key), 则它们同属于一个realm(个人理解是一个用户空间)
- realm的名字是大小写敏感。通常用全大写。推荐名字和DNS的大写表达式一样。如EXAMPLE.COM
- Principal 主体
- principal对应与认证服务数据库的条目。用于对应指定realm的用户,主机或者服务。
- 表达式如下 component1/component2/.../componentN@REALM,但目前最多只使用两个组件 Name[/Instance]@REALM
- 表达用户的例子 test@EXAMPLE.COM, test/admin@EXAMPLE.COM, root/admin@EXAMPLE.COM
- 表达服务的例子 ftp/xxx.example.com@EXAMPLE.COM
- 有一些principal即不用来指代用户,也不用于指代服务,而是在Kerberos认证系统的操作中扮演一个角色。一个首要的例子就是krbtgt/REALM@REALM,这个principal和它的相关的密钥会被用来加密Tikcet Granting Ticket,krb就是指kerberos, tgt就是指Ticket Granting Ticket,所以这个特殊的principal前缀就是krbtgt。只有KDC拥有这个principal和它的相关的密钥,所以TGT才不能被伪造.
- Ticket 票据
-
- 用户用ticket向应用服务器证明身份的真实性。
- ticket是由AS(认证服务)和应用服务本身才知道的key加密生成
- 由于ticket签发后无法收回,ticket通过过期时间限制
- Ticket分两种:
- Ticket Granting Ticket,TGT:这是KDC中的Authentication Server(简称AS)产生的,TGT是向Ticket Granting Server(TGS)用于表明自己真实身份的东西
- Service Ticket:这是KDC中的Ticket Granting Server(简称TGS)产生的,Service Ticket 是用于向应用服务器表明自己身份的东西
- Session Key 会话密钥
- 用户和应用服务和KDC之间共享的secret是一个长期密钥。这个secret不适合在不授信网络传输。所以KDC会生成一个会话密钥,此密钥在KDC和用户,用户和服务的认证会话中使用。
- Authenticator 鉴别符
- 因为此协议用于非授信网络,如果应用服务只用ticket认证用户,会出现ticket被中介者劫持并假冒的风险。所以协议增加了Authenticator数据。
- Authenticator数据是用双方才知道的session key加密client info和一个时间戳。
- 应用服务可以使用session key解密Authenticator,根据ticket和Authenticator里的client info认证用户。
- kvno 密钥版本号
- 当用户修改密码或者管理员为应用服务器升级密钥的时候,这个修改会被以增加计数器计数的形式记录下来。计数器的当前值 表示密钥的版本,这被称为Key Version Number, 或者简称为kvno.
- KDC 密钥分发中心,包含三个组件
- principal数据库
- Authentication Server (AS) 认证服务
-
-
- KDC中的认证服务,用于客户端的初始认证。AS会分发一个特殊的ticket,Ticket Granting Ticket,简称为TGT
-
- Ticket Granting Server (TGS) 票据授予服务
- KDC中的票据授予服务,通过提供的合法TGT,为认证的主体发放具体票据。
- keytab
- keytab是一个包含了Kerberos princpals和加密的密钥的一个文件,这个加密的密钥是从Kerberos的用户密码转化来的,当你的用户密码改变了,你就需要重新生成你的keytabs。你可以在client上用kinit -k -t keytab principal无密码的认证principal用户或者服务,获取principal对应的ticket granting ticket(TGT)文件。
认识了这些新老朋友之后,让我们通过客户端获取身份验证并访问目标应用服务的例子来详细了解Kerberos协议。
操作流程
- Authentication Server Request (AS_REQ)
-
- 客户端向KDC发送认证请求
- AS_REQ = ( PrincipalClient , PrincipalService , IP_list , Lifetime )
- PrincipalClient是请求认证的主体,如test/normal@EXAMPLE.COM
- PrincipalService是请求的服务主体,这里一般是krbtgt/REALM@REALM。但也可以直接填写最终要访问的服务主题
- IP_list可以为空
- Lifetime 想获得Ticket的最长的有效时间
- 由于这个请求可能被非法用户利用,发送大量请求获取TGT,用于暴力破解KDC的主密钥。所以Kerberos5引入了Pre-Authentication。启用后,客户端需要对原来的AS_REQ使用客户端的密钥加密,由于只有KDC知道客户端的密钥,所以可以用来应对非法用户。
- Authentication Server Reply (AS_REP)
- AS检查PrincipalClient,PrincipalService是否存在
- 随机生成session key,这个我们命名为SK_TGS。客户端和KDC用这个加密会话。
- AS生成TGT(票据授予票据)。
- TGT = ( PrincipalClient , krbtgt/REALM@REALM , IP_list , Timestamp , Lifetime , SKTGS )
- AS用客户端的密钥加密SK_TGS等数据后,和TGT一并返回。
- AS_REP = { PrincipalService , Timestamp , Lifetime , SK_TGS }K_User { TGT }K_TGS
- K_User是客户端的密钥
- K_TGS是TGS的密钥
- Ticket Granting Server Request (TGS_REQ)
- 客户端用密钥解密AS_REP中的第一部分后获取SK_TGS。
- 客户端用SK_TGS加密Authenticator并连同TGT向TGS发送获取指定服务票据的请求
- Authenticator = { PrincipalClient , Timestamp }SK_TGS
- TGS_REQ = ( PrincipalService , Lifetime , Authenticator) { TGT }K_TGS
-
-
-
- PrincipalService,指定应用服务
-
-
- Ticket Granting Server Replay (TGS_REP)
- TGS检查PrincipalService存在
- 用K_TGS解开TGT,验证TGT内容
- TGT是否过期
- PrincipalClient是否一致
- IP_list检查
- 检查成功后,生成随机的session key,这个我们命名为SK_Service。客户端和应用服务会用这个加密会话。
- TGS生成票据T_Service
- T_Service = ( PrincipalClient , PrincipalService , IP_list , Timestamp , Lifetime , SK_Service )
- TGS用SK_TGS加密SK_Service等数据后,和T_Service一并返回。
- TGS_REP = { PrincipalService , Timestamp , Lifetime , SK_Service }SK_TGS { TService }K_Service
- K_Service是应用服务的密钥
- Application Request (AP_REQ)
- 客户端用SK_TGS解密TGS_REP中数据获得会话密钥SK_Service和票据T_Service
- AP_REQ在协议中没有标准的实现,由应用开发人员指定认证规则。常见实现如下
- 客户端用SK_Service加密Authenticator并连同T_Service向应用服务发送认证请求
- Authenticator = { PrincipalClient , Timestamp } SK_Service
- AP_REQ = Authenticator { T_Service }K_Service
- Application Replay (AP_REP)
- 应用服务用自己的密钥解开AP_REQ获取会话密钥SK_Service等数据,再用会话密钥解开Authenticator并验证内容。(和TGS流程类似)
- 票据是否失效
- PrincipalClient是否一致
- IP_list检查
- 检查成功后,返回AP_REP,认证结束。
- 如果客户端在请求的时候,开启了双向认证。应用服务会用SK_Service在此加密Authenticator中的Timestamp并在AP_REP返回给客户端解密校验。
回到开篇的问题,Hadoop为什么选择使用Kerberos作为其身份验证机制,主要有以下几个优点:
- 安全性强:Kerberos采用了基于密钥的加密技术,能够确保通信过程中不会被攻击者窃听或篡改。
- 灵活性强:Kerberos支持可扩展性强的分布式架构,可以适应大型的计算机网络环境。
- 可靠性高:Kerberos协议具有高度可靠性,能够在发现安全漏洞时自动更新密钥。
- 易于管理:Kerberos可以集成到Hadoop集群的管理系统中,方便管理员对用户进行身份认证和管理。