Kerveros解决的是如何证明某个人就是他声称的那个人。
采用的方法:有一个仅存在A和B之间的秘密,如果有人对A声称自己就是B,那么A通过让B提供这个秘密来证明这个人就是B。
这样的验证过程中有几个问题需要解决:
1.秘密怎样表示
2.B如何向A提供这个秘密
3.A如何识别这个秘密
4.秘密是怎么生成,并且仅告知A和B
首先明白几个概念:
Long-term key:
账户的原始密码,不经常改变。有一个原则:被long-term key加密的数据不应该 在网络上传输。因为如果这些数据被恶意获取到,原则上只要有足够的时间,就可 以被破解并获取密码。
Master key:
一个账户的密码应该仅限于账户本身知道,甚至对于管理者来说也是保密的。 但是账户的密码又是身份的证明,所以一般将密码用hash加密的方式进行加密, 密码加密后就叫做master key。由于hash的方式是不可逆的,这就在保证密码的 安全同时master key又同时具有与原始密码相同的认证效果。
short-term key/session key:
由于被long-term key加密的数据不应该在网络上传输,所以用session key 来加密 需要进行网络传输的数据。这种key只在一段时间内有效。即使加密的数据被恶意 获取,等到被计算出的时候,该key也已经失效了。
客户端:
Kerberos安全领域的连接方
服务端:
Kerberos安全领域的被连接方
KDC:
客户端和服务端共同信任的第三方,并且拥有着所有客户端和服务端的账户名称 以及账户密码派生出来的master key
TGT:
客户端用于能够连接服务端的资格,于某个具体的服务端无关。以数据包的形式 存在。
Ticket:
客户端用于连接服务端的凭证,与具体的某个服务端相关。以数据包的形式存 在。
在整个kerberos的认证过程中,可分为以下三个步骤:
1.客户端向KDC申请获取TGT,目的是让自己有资格去访问服务端
2.获取到TGT后,客户端向KDC申请用于访问服务端的ticket
3.获取到ticket后,客户端申请访问服务端。
第一步:
如果客户端想要连接服务端,首先客户端向KDC申请获取TGT,在KDC收到申请后,生成一个用于该客户端和KDC进行安全通信的session key,为了保证该session key只能用于KDC和该客户端,KDC会用自己的master key和客户端的master key对该session key进行加密,用自己的master key对session key进行加密后还包含了一些该客户端的信息。这样就有了两份数据包,一份是用KDC自己的master key加密的session key,其中包含了客户端信息,这一份数据包是准备留给自己使用的,叫做TGT。还有一份是用客户端的master key对session key进行加密的数据包。KDC将这两份数据包都发送给客户端。客户端收到这样的数据包后,该客户端就有了访问服务端的资格。
第二步:
客户端收到数据包后,首先使用自己的master key对第二份数据包进行解密从而获取到了自己和KDC之间的session key。然后客户端生成自己的鉴别码,鉴别码主要是客户端自身的身份信息和想要连接的服务端的信息。然后客户端使用session key对鉴别码进行加密。随后客户端将重新加密后的数据包连同TGT一起发送给KDC,用于申请连接服务端的数据包。当KDC收到这两份数据包后,首先使用自己的master key对TGT进行解密从而获得KDC与该客户端的session key和该客户端的一些信息。获得了session key之后,使用session key去解密另一份数据包从而获得了该客户端的一些信息和该客户端想要连接的服务端的信息。KDC前后获得了两份客户端的信息,两份信息进行验证,若一致则验证通过。
KDC就会生成该客户端用于连接服务端的session key。为了保证该session key只让该客户端和该服务端知道,会生成两份。其中一份是用服务端的master key对该session key进行加密,并且还包含了该客户端的信息。另外一份是由该客户端的master key进行加密的session key。然后KDC将这两份信息都发送给客户端。客户端收到这两份信息后首先使用自己的master key对自己的那份数据包进行解密从而获得session key。获得session key之后,客户端会生成自己的鉴别码,这时的鉴别码包含的信息是客户端的身份信息和时间戳。然后使用解密后的session key对鉴别码再进行加密。随后将加密后的数据包和另外一份数据包发送给服务端。
第三步:
服务端收到这两份数据包后,首先使用自己的master key去解密自己的那份数据包从而获得了服务端与客户端的session key和客户端的身份信息,然后使用解密得来的session key去解密另外一份数据包从而获得了时间戳信息和客户端的身份信息。服务端前后解密得到了两份客户端的信息和一份时间戳信息,首先会根据时间戳信息和当前时间进行比较,如果没有超时,并且两份身份信息验证通过,则允许连接。
Kerberos的双向认证:客户端也能对服务端进行认证。
如果客户端想要对服务端进行认证,会在它向服务端发送的身份信息中设置一个需要认证的flag,服务端在对客户端认证成功后,会把鉴别码中的时间戳提取出来,通过session key进行加密发送给客户端,客户端使用session key进行解密后,与之前的时间戳进行对比,如果一致,则可以证实该服务端是该客户端想要访问的服务端。
Q&A:
Q1:在第一步中KDC为什么将两份数据包都发送给客户端,而不是自己留一份,然后将另一份发送给客户端。
A:由于KDC会面对不同的客户端,每个客户端与自己都一个特有的session key。如果自己留一份,那么存在一个客户端就存在一份session key。并且在客户端与KDC连接的时候,需要进行遍历选择,这样的维护成本较高。所以KDC不会保存这个session key,而是选择发送给客户端,然后客户端在连接KDC时,再提供这个session key。
Q2:在第二步中KDC为什么将两份数据都发送给客户端,而不是分别将数据包发送给服务端和客户端。
A:原因和上述类似,服务端也需要面对不同的客户端,如果将数据包发送给服务端,那么服务端就需要去维护这些session key信息。还有一点是为了防止在发送个客户端和服务端时因为网络原因不能同步收到,会导致不能正常访问。
Q3:时间戳是用来验证什么的?有什么具体作用?
A:在客户端向服务端发送两个数据包时,如果数据包被恶意截取,然后将数据包作为自己的身份信息冒充客户端,这样依旧能和服务端建立连接。为了解决这样的问题,客户端在鉴别码中添加时间戳信息,在服务端接收到鉴别码信息后,通过与当前时间进行比较判断是否连接。并且在双向认证中,时间戳也作为认证信息存在。
Q4:在双向认证中,为什么要把时间戳提取出来,而不是把整个鉴别码都发送给客户端进行认证?
A:原因是为了防止在客户端向服务端发送鉴别码的时候被恶意获取,然后将数据包作为自己的身份信息冒充服务端获得客户端的认证。
Q5:在第二步中,KDC与客户端之间的session key和TGT的关系是什么。
A:session key有自己的生命周期,同时和TGT是相互关联的,当session key过期,TGT也就失效,所以当session key失效的时候,客户端就需要重新向KDC申请获取TGT。
1.机器部署:
IP地址 主机名 角色
10.251.27.161 dqynj0270161 KDC
10.251.27.162 dqynj0270162 Client
10.251.27.163 dqynj0270163 Client
Root用户进行操作。
2.在dqynj0270161主机上安装krb5-server,krb5-workstation,krb5-libs,openldap-clients
命令:yum install krb5-server -y
报错:原因是将要下载的lrb5-libs包下的一个文件与已存在的某个包有冲突
解决方法:将已存在的有冲突的那个包删除
命令:rpm -e libkadm5-1.15.1-8.el7.x86_64
报错:krb5-devel-1.15.1-8.el7.x86_64依赖这个将被删除的包,所以不能删除
解决方法:将该包也进行删除
命令:rpm -e krb5-devel-1.15.1-8.el7.x86_64
报错:openssl-devel-1:1.0.2k-8.el7.x86_64依赖这个将被删除的包
解决方法:将该包也进行删除
命令:rpm -e openssl-devel-1:1.0.2k-8.el7.x86_64
不报错,再依次删除另外两个包。
删除成功后,也就是冲突的包就被删除了。然后重新执行命令进行安装krb5-server
命令:yum install krb5-server -y
krb5-server安装成功。
3.安装krb5-workstation:yum install krb5-workstation -y
安装成功
4.安装openldap-clients:yum install openldap-clients -y
安装成功。
Principal:
认证的主体,简单的说就是用户名。在Kerberos中标记一个唯一的身份。Kerberos 为 Principal分配tickets使其可以访问由Kerberos加密的Hadoop服务。
Keytab:
keytab是包含Principals和加密的Principal key的文件,keytab文件对于每个host 是 唯一的,应被妥善保管,只有少数的用户可以访问。
Realm:
类似namespace,在编程语言中,变量名只有在某个namespace下才有意义,同样, 一个Principal只有在某个realm下才有意义,所有realm可以看做成一个容器或者 是 空间,realm的命名一般采用大写,如:EXAMPLE.COM,而Principal的命名规则是 PrincipalName+@+realm
5.安装成功后配置KDC服务
修改/etc/krb5.conf文件
配置说明:
[logging]:表示server端的日志打印位置,一般不需要更改。
[libdefaults]:每种连接的默认配置,需要注意以下几点。
default_realm:kerberos应用程序的默认领域,也就是上述中的realm。所有 的Principal都将带有这个领域标志。
ticket_lifetime:凭证生效的时限,一般为24小时
renew_lifetime:凭证最长可以被延期的时限,一般是7天,
Clockskew:时间偏差,默认5分钟,服务器与凭证的时间差必须在5分钟内。
[realm]:列举使用的realm
Kdc:代表kdc所在的位置
admin_server:代表admin的位置
6.再修改/var/kerberos/krb5kdc/kdc.conf文件
配置说明:
Kdcdefaults:kdc相关配置,这里只设置了端口信息
Realms:realm的配置
HADOOP.COM:设定的realm领域,与/etc/krb5.conf中设置的要一致
Master_key_type:默认使用的校验方式,JAVA使用aes256-cts验证方式需要安装JCE 包。不推荐使用
Max_renewable:要大于或等于/etc/krb5.conf中的renew_lifetime配置
Max_life:要大于或等于/etc/krb5.conf中的ticket_lifetime配置
Acl_file:标注了admin的用户权限。
Admin_keytab:KDC进行校验的keytab
Supported_enctypes:支持的校验方式
7.配置/var/kerberos/krb5kdc/kadm5.acl文件:
代表用户principals的名字后缀是[email protected]的,都是admin用户,拥有全部的权限。后面的*即代表着所有的权限。在KDC上我们需要编辑acl文件去设置权限。Kerberos会使用该文件来管理对kerberos database的访问权限。
8.创建kerberos数据库:kdb5_util create -r HADOOP.COM -s
其中-s表示生成stash file,用来存储master server key(krb5kdc),-r表示 指定一个realm,当数据库创建好之后,在/var/kerberos/中可以看到生成的 principal文件
提示输入数据库管理员密码:kerberos
再次输入密码进行验证。
如果需要重建数据库,将/var/kerberos/krb5kdc目录下的principal相关的文件删除即可。
9.数据库创建好之后,添加database administrator,也就是能管理database的principal,至少要添加一个principal来使得kerberos的管理进程kamind能够在网络上与程序kadmin进行通讯。
命令:kadmin.local -q “addprinc admin/admin”
用户名:admin/admin,但是实际上的用户名是admin/[email protected]
为用户设置密码:admin
再创建一个administrative principals 。
命令:kadmin.local -q “addprinc cloudera/admin”
设置密码:cloudera
10.设置kerberos服务为开机启动
11.查看防火墙状态,如果属于开启状态则关闭。
临时关闭:systemctl stop firewalld.service
永久关闭:systemctl disable firewalld.service
12.启动krb5kdc和kadmind进程
service krb5kdc start
service kadmin start
查看启动状态:
service krb5kdc status
13.集群其他节点安装kerberos client
将这两台机器上的/etc/krb5.conf文件与KDC主机上的该文件保持一致。
14.Kerberos的常用命令:
kinit UserName 使用该用户进行登录,获取身份认证,需要输入密码
klist 查看当前用户的认证信息
kinit -R 更新ticket
kdestroy 退出当前认证用户
kadmin.local -q “list_principals” 列出所有的认证用户
kadmin.local -q "addprinc UserName " 添加用户,需要输入密码
kadmin.local -q "delprinc UserName " 删除认证用户
在KDC主机上的root用户下输入命令行:kadmin.local
然后可以键入?进行参数提示。常用的有:
1.查看用户列表:listprincs
2.修改账户密码:change_password principalsName 然后输入想要更新的密码
3.创建用户:add_principal principalsName 然后给该用户设置一个密码
4.删除用户:delete_principal principalsName
5.只导出用户keytab文件:xst -k admin.keytab -norandkey admin/admin
在添加之前,首先确定几件事:
1.KDC已经安装好并且在运行
2.CM的server中安装了openldap-clients
3.为CM创建了超级管理员,使其能够有权限创建其他principals,如上面的cloudera
4.将KDC配置为允许可更新的票证:在kdc.conf文件中添加max_life和max_renewable
前者表示服务端允许的service ticket最大生命周期,后者表示服务端允许的service ticket更新周期。
开启流程:
1.表示开启:
2.确定上述已说明的四个前提条件:
3.填写realm和KDC所在主机名称,以及kerberos的加密类型。这里的加密类型必须跟KDC实际支持的加密类型要匹配(即kdc.conf中的值)
4.勾选通过CM来管理krb5.conf,可以通过CM的管理界面来部署krb5.conf
5.填写超级管理员的账户和密码,如上述创建的用户cloudera
在页面查看启动结果时,其他组件都正常,只有HUE启动不正常。查看日志,报错:
Couldn’t renew kerberos ticket in order to work around Kerberos 1.8.1 issue. Please check that the ticket for ‘hue/[email protected]’ is still renewable:
$ klist -f -c /var/run/hue/hue_krb5_ccache
If the ‘renew until’ date is the same as the ‘valid starting’ date, the ticket cannot be renewed. Please check your KDC configuration, and the ticket renewal policy (maxrenewlife) for the ‘hue/[email protected]’ and `krbtgt’ principals.
根据提示执行:klist -f -c /var/run/hue/hue_krb5_ccache
查看原因是ticket无法更新
进入命令行执行:kadmin.local,再执行
问题解决。CDH启用kerberos成功。