Kerberos认证简述


发布于 2024-04-07 / 69 阅读 / 0 评论 /
官网中对Kerberos的介绍是“Kerberos is a network authentication protocol. It is designed to provide strong authentication for client/server applications by using secret-key cryptography”。也就是说Kerberos是一个网络授权协议,主要通过密钥加密实现C/S应用的强授权。

1.Kerberos相关概念

主要有以下关键词。

1.1.Long-term Key/Master Key

长期内保持不变的Key,使用原则:被Long-term Key加密的数据不应该在网络上传输。

原因在于,一旦这些被Long-term Key加密的数据包被恶意的网络监听者截获,在原则上,只要有充足的时间,他是可以通过计算获得你用于加密的Long-term Key的——任何加密算法都不可能做到绝对保密。

1.2.Short-term Key/Session Key

我们使用另一种Short-term Key来加密需要进行网络传输的数据。由于这种Key只在一段时间内有效,即使被加密的数据包被黑客截获,等他把Key计算出来的时候,这个Key早就已经过期了。

1.3.KServer-Client

Client和Server之间的Key,代表Client自身Identity的信息,以明文传递。将Client的Identity使用KServer-Client作为Public Key,并采用对称加密算法进行加密。

1.4.SServer-Client

通过让被认证的一方提供一个仅限于他和认证方知晓的Key来鉴定对方的真实身份。而被这个Key加密的数据包需要在Client和Server之间传送,所以这个Key不能是一个Long-term Key,而只可能是Short-term Key,这个可以仅仅在Client和Server的一个Session中有效,所以我们称这个Key为Client和Server之间的Session Key(SServer-Client)。

1.5.principal

认证的主体,简单来说就是"用户名"

1.6.realm

realm有点像编程语言中的namespace。在编程语言中,变量名只有在某个"namespace"里才有意义。同样的,一个principal只有在某个realm下才有意义。

所以realm可以看成是principal的一个"容器"或者"空间"。相对应的,principal的命名规则是"what_name_you_like@realm"。

在kerberos, 大家都约定成俗用大写来命名realm, 比如"EXAMPLE.COM"。

1.7.password

某个用户的密码,对应于kerberos中的Master Key。password可以存在一个keytab文件中。所以kerberos中需要使用密码的场景都可以用一个keytab作为输入。

1.8.credential

credential是“证明某个人确定是他自己/某一种行为的确可以发生”的凭据。在不同的使用场景下, credential的具体含义也略有不同:

(1)对于某个principal个体而言,他的credential就是他的password。

(2)在kerberos认证的环节中,credential就意味着各种各样的ticket。

2.KDC

KDC全称是Kerberos Distribution Center。

KDC在整个Kerberos Authentication中作为Client和Server共同信任的第三方起着重要的作用,而Kerberos的认证过程就是通过这3方协作完成。

基本架构如下图所示:

KDC主要由两部分组成:Authentication Server和Ticket Granting Server。

3.认证过程

认证过程如下图所示:

从图中可知,认证过程分为以下6个步骤:

(1)第一步:用户向KDC发送请求验证自己的身份

(2)第二步:KDC确认用户身份,并用协议开始前Client与KDC之间的密钥将TGT加密回复给Client。此时只有真正的Client才能利用它与KDC之间的密钥将加密后的TGT解密,从而获得TGT。

(3)第三步:Client将之前获得TGT和要请求的服务信息(服务名等)发送给KDC,KDC中的Ticket Granting Service将为Client和Service之间生成一个Session Key用于Service对Client的身份鉴别。然后KDC将这个Session Key和用户名,用户地址(IP),服务名,有效期, 时间戳一起包装成一个Ticket(这些信息最终用于Service对Client的身份鉴别)发送给Service, 不过Kerberos协议并没有直接将Ticket发送给Service,而是通过Client转发给Service

(4)第四步:此时KDC将刚才的Ticket转发给Client。由于这个Ticket是要给Service的,不能让Client看到,所以KDC用协议开始前KDC与Service之间的密钥将Ticket加密后再发送给Client。同时为了让Client和Service之间共享那个密钥(KDC在第三步为它们创建的Session Key),KDC用Client与它之间的密钥将Session Key加密随加密的Ticket一起返回给Client。

(5)第五步:为了完成Ticket的传递,Client将刚才收到的Ticket转发到Service. 由于Client不知道KDC与Service之间的密钥,所以它无法篡改Ticket中的信息。同时Client将收到的Session Key解密出来,然后将自己的用户名,用户地址(IP)打包成Authenticator用Session Key加密也发送给Service。

(6)第六步:Service 收到Ticket后利用它与KDC之间的密钥将Ticket中的信息解密出来,从而获得Session Key和用户名,用户地址(IP),服务名,有效期。然后再用Session Key将Authenticator解密从而获得用户名,用户地址(IP)将其与之前Ticket中解密出来的用户名,用户地址(IP)做比较从而验证Client的身份。 如果Service有返回结果,将其返回给Client。

4.配置文件

主要有三个配置文件。

4.1.krb5.conf

krb5.conf是kerberos协议配置文件,配置文件具体内容介绍如下所示。

[logging] // 表示 server 端的日志的打印位置
[libdefaults] //每种连接的默认配置,需要注意以下几个关键的小配置
       default_realm = JAVACHEN.COM // 设置 Kerberos 应用程序的默认领域。如果您有多个领域,只需向 [realms] 节添加其他的语句。
       udp_preference_limit = 1 // 禁止使用 udp 可以防止一个Hadoop中的错误
       clockskew // 时钟偏差是不完全符合主机系统时钟的票据时戳的容差,超过此容差将不接受此票据。通常,将时钟扭斜设置为 300 秒(5 分钟)。这意味着从服务器的角度看,票证的时间戳与它的偏差可以是在前后 5 分钟内。
       ticket_lifetime // 表明凭证生效的时限,一般为24小时。
       renew_lifetime //  表明凭证最长可以被延期的时限,一般为一个礼拜。当凭证过期之后,对安全认证的服务的后续访问则会失败。
[realms] // 列举使用的 realm。
       kdc // 代表要 kdc 的位置。格式是 机器:端口
       admin_server // 代表 admin 的位置。格式是 机器:端口
       default_domain // 代表默认的域名
[appdefaults] // 可以设定一些针对特定应用的配置,覆盖默认配置。

共有四个主要模块。

4.2.kdc.conf

kdc.conf是KDC Server配置文件,具体说明如下所示。

[realms]
       JAVACHEN.COM // 是设定的 realms。名字随意。Kerberos 可以支持多个 realms,会增加复杂度。大小写敏感,一般为了识别使用全部大写。这个 realms 跟机器的 host 没有大关系。
       master_key_type // 和 supported_enctypes 默认使用 aes256-cts。由于,JAVA 使用 aes256-cts 验证方式需要安装额外的 jar 包(后面再做说明)。推荐不使用,并且删除 aes256-cts。
       acl_file // 标注了 admin 的用户权限,需要用户自己创建。文件格式是:Kerberos_principal permissions [target_principal] [restrictions]
       supported_enctypes // 支持的校验方式。
       admin_keytab // KDC 进行校验的 keytab。

主要配置realm,定义KDC服务端信息。

4.3.kadm5.acl

kadm5.acl是admin用户权限配置文件

5.Kerberos认证操作案例

关于kerberos的管理,可以使用kadmin.local或kadmin命令,使用哪个则取决于账户和访问权限:

(1)如果有访问 kdc 服务器的 root 权限,但是没有 kerberos admin 账户,使用 kadmin.local

(2)如果没有访问 kdc 服务器的 root 权限,但是有 kerberos admin 账户,使用 kadmin

5.1.创建管理员

假设密码为root,则有以下两种方式:

kadmin.local -q "addprinc root/admin"
echo -e "root\nroot" | kadmin.local -q "addprinc root/admin"

第一种方法需要交互式输入密码

5.2.查询用户

有两种方式:

kadmin -p root/admin -q "list_principals"
kadmin.local -q "list_principals"

第一种需要输入密码,第二种不需要输入密码。

5.3.创建一个测试用户

用户名tbdstest,密码为tbdstest,命令如下。

echo -e "tbdstest\ntbdstest" | kadmin.local -q "addprinc tbdstest"

命令在交互窗口输入。

5.4.创建或更新tbdstest用户的ticket

有以下两种用法:

kinit tbdstest #基于密码进行认证
kinit -kt /tmp/tbds.keytab tbdstest #基于密钥进行认证

基于密码的认证需要在交互窗口输入密码。

5.5.查看tbdstest用户的ticket

直接使用klist命令:

klist tbdstest

5.6.销毁tbdstest用户的ticket

直接使用kdestroy命令:

kdestroy

5.7.密钥操作

抽取密钥并将其储存在本地 keytab 文件 /etc/krb5.keytab 中。这个文件由超级用户拥有,所以您必须是 root 用户才能在 kadmin shell 中执行以下命令:

kadmin.local -q "ktadd kadmin/admin"
klist -k /etc/krb5.keytab

5.8.删除用户tbdstest

有两种方法:

kadmin -p root/admin -q "delprinc user2"
kadmin.local -q "delprinc user2"

只能通过超级用户进行删除

5.9.kadmin.local进入本地管理员模式

kadmin.local #进入本地管理员模式,可执行以下命令:

? #查看支持的命令列表

listprincs #查看所有principal

addprinc -randkey hdfs/node3 ##生成随机key的凭据

addprinc -pw 123456 jack/node4 ###生成指定key的凭据

delprinc jack/node4 #删除凭据

ktadd -norandkey -k /root/tbdstest.keytab tbdstest #导出tbdstest的凭据

xst -norandkey  -k /root/node4.keytab jack/node4 #导出jack/node4的凭据

xst -norandkey -k /tmp/test.keytab tbdstest hdfs/node3 jack/node4 #将多个principal生产一个keytab

我们就是通过以上方法来生成新用户的keytab。

5.10.注意事项

上一节生成的jack/node4是指定key,如果通过ktadd -k /root/node4.keytab jack/node4导出密钥后,创建时指定的key失效。

失效的原因是:每次生成秘钥文件时,密码可能会进行随机改变,后续再通过指定key进行认证时会报kinit: Password incorrect while getting initial credentials生成密钥时。

解决方案:命令行中添加"-norandkey"即可解决问题,上一节也有对应的案例介绍。