之前非常担心的一件事就是如果有人拿到了hdfs超级管理员帐号,直接把数据rm -rf怎么办?有了Kerberos,就可以轻松防止这样的事情发生。Kerberos 协议实现了比“质询-响应”模式协议更高的安全性:第一,在身份验证过程中,所有的数据都使用不同的密码进行加密,避免了相关验证信息的泄漏;第二,客户端和服务器会相互验证对方的身份,避免了 中间人攻击 ;第三,客户端和服务器间的时间差被严格限制,避免了 回放攻击 。与 WINDOWS 系统中的 用户安全令牌 类似, Kerberos 服务通过“ 加密的票据(防止篡改) ”验证用户身份和提供用户访问权限;Kerberos 服务可以通过使用 会话密钥 确保在会话中数据的机密性和完整性。
Kerberos相关术语
Kerberos认证过程
Kerberos 的认证过程如下图所示。我们可以简单的理解为,User 或者 Service 会用 Principal 到 AS 去认证(KRB_AS_REQ),AS 会返回一个用 Principal Key 加密的 TGT(KRB_AS_REP),这时候只有 AS 和这个 Principal 的使用者可以识别该 TGT。在拿到加密的 TGT 之后,User 或者 Service 会使用 Principal 的 Key 来解密 TGT,并使用解密后的 TGT 去 TGS 获取 Service Ticket(KRB_TGS_REQ, KRB_TGS_REP)。在 Kerberos 认证的集群中,只有拿着这个 Service Ticket 才可以访问真正的 Server 从而实现自己的业务逻辑(KRB_AP_REQ, KRB_AP_REP)。一般我们将 TGT 的存放文件,称为 Kerberos Confidential 文件,默认的存放目录为/tmp,文件名则由 krb5cc 和用户的 id 组成,例如“/tmp/krb5cc_0”为root的 confidential 文件。
图示:Kerberos 认证过程
Cloudera平台集成Kerberos
Cloudera提供了非常简便的Kerberos集成方式,基本做到了自动化部署。
系统:CentOS 7.2
操作用户:admin
角色分布如下:
角色 | 部署节点 | 机器类型 |
---|---|---|
KDC, AS, TGS | 192.168.1.1 | VM |
Kerberos Agent | 192.168.1.[2-17] | VM、Master、Slave |
- KDC已经安装好并且正在运行
- 将KDC配置为允许renewable tickets with non-zerolifetime,我们在之前修改kdc.conf文件的时候已经添加了
max_life
和max_renewable_life
这个2个属性,前者表示服务端允许的Service ticket最大生命周期,后者表示服务端允许的Service ticket更新周期。这2个属性必须分别大于等于客户端对应的配置ticket_lifetime
和renew_lifetime
。我们假设,不这样进行配置:ticket_lifetime = 8d, max_life = 7d, renew_lifetime = 25h, max_renew_life = 24h,那么可能造成的结果就是当service持有的票据超过24小时没有去更新,在第24.5小时的时候去进行更新,请求会遭到拒绝,报错:Ticket expired while renewing credentials
,永远无法进行正常更新。对于Cloudera来说,因为更新机制被透明(Cloudera有renew进程会去定期更新),即使我们手动使用``modprinc -maxrenewlife 1week krbtgt/DOMAIN.COM@DOMAIN.COM` 进行更新,也无济于事。 - 在Cloudera Manager Server上安装openldap-clients;
- 为Cloudera Manager创建了超级管理员principal,使其能够有权限在KDC中创建其他的principals;
再次确认完毕后进入如下步骤:
- 进入 Cloudera Manager Admin Console 界面并且点击 cluster 右边的按钮选择Enable Kerberos;
- 点击 Continue,进入下一页进行配置,要注意的是:这里的 Kerberos Encryption Types 必须跟KDC实际支持的加密类型匹配(即kdc.conf中的值),这里使用了默认的
aes256-cts
,注意,这里的 Kerberos Encryption Types 必须和/etc/krb5.conf中的default_tgs_enctypes
、default_tkt_enctypes
和permitted_enctypes
三个选项的值对应起来,不然会出现集群服务无法认证通过的情况! - 点击 Continue,进入下一页,这一页中不勾选 Manage krb5.conf through Cloudera Manager ,否则会修改掉之前配置的acl,造成 enable kerberos 失败;
- 点击 Continue,进入下一页,输入 Cloudera Manager Principal 的管理员账号和密码,注意输入账号的时候要使用@前要使用全称,本文使用的是
cdh-master/admin@DOMAIN.COM
; - 点击 Continue,进入下一页,导入 KDC Account Manager Credentials;
- 点击 Continue,进入下一页,Restart Cluster 并且Eenable Kerberos;
之后 Cloudera Manager 会自动重启集群服务,启动之后会提示 Kerberos 已启用。在 Cloudera Manager 上启用 Kerberos 的过程中,会自动做以下的事情:
- 集群中有多少个节点,每个账户就会生成对应个数的 principal ;
- 为每个对应的 principal 创建 keytab;
- 部署 keytab 文件到指定的节点中;
- 在每个服务的配置文件中加入有关 Kerberos 的配置;
其中包括Zookeeper服务所需要的 jaas.conf
和 keytab 文件都会自动设定并读取,如果用户仍然手动修改了Zookeeper的服务,要确保这两个文件的路径和内容正确性。
- keytab 是包含 principals 和加密 principal key 的文件 ;
- keytab 文件对于每个 host 是唯一的,因为 key 中包含 hostname ;
- keytab 文件用于保存纯文本密码,实现到 kerberos上 验证一个主机的 principal ;
启用之后访问集群的所有资源都需要使用相应的账号来访问,否则会无法通过 Kerberos 的 authenticatin。
除此之外,对于特定的服务需要做额外配置,本文只介绍HDFS、YARN、HBase,其余服务请参照官方文档自行进行配置。
对于HDFS,需要开启Web Concole 的认证,以防未认证用户访问资源界面,请在HDFS服务的Configuration中进行配置:
Enable Kerberos Authentication for HTTP Web-Consoles = true
对于YARN,需要开启Web Concole 的认证,以防未认证用户访问资源界面,请在YARN服务的Configuration中进行配置:
Enable Kerberos Authentication for HTTP Web-Consoles = true
对于HBase需要开启 Thrift 认证:
HBase Thrift Authentication = auth
完成修改后,通过Cloudera Manager对HDFS服务进行重启。
相关测试
完成部署后,需要进行相关测试,以验证Kerberos是否被正常开启,本文纯属抛砖引玉,对部分服务进行了验证。
基本功能测试
在192.168.1.1 KDC 服务端上新建principal:
kadmin.local -q "addprinc <user_name>/DOMAIN.COM@DOMAIN.COM"
在客户端192.168.1.2上新建principal:
kinit cdh-master/admin@DOMAIN.COM
kadmin -q "addprinc <user_name>/DOMAIN.COM@DOMAIN.COM"
销毁ticket缓存:
kdestroy
查看当前ticket缓存,这时应会报错No credentials cache found (ticket cache FILE:/tmp/krb5cc_0)
:
klist -f
重新获取ticket:
kinit <user_name>/DOMAIN.COM@DOMAIN.COM
查看当前ticket缓存,应该不会报错:
klist -f
Hive功能测试
CLI测试,首先进行principal初始化
kadmin -q "addprinc hive/test@DOMAIN.COM"
kinit hive/test@DOMAIN.COM
在没有配置 kerberos 之前,想要通过 hive 用户运行 hive 命令需要执行sudo,现在配置了 kerberos 之后,不再需要 sudo 了,hive 会通过 ticket 中的用户去执行该命令:
CREATE DATABASE test;
USE test;
CREATE TABLE t(id int);
DROP TABLE t;
DROP DATABASE test;
Beeline/JDBC测试:
beeline --verbose=true
beeline > !connect jdbc:hive2://${HIVE_SERVER2_HOSTNAME}:10000/default;principal=hive/${HIVE_SERVER2_HOSTNAME}@DOMAIN.COM;
HUE Sqoop Action测试,唯一需要注意的是,在提交 Action的时候需要选择credential方式,hive shell action请选择 hcat,hive server2 action 请选择hive2,否则无法通过认证。
HBase on HUE功能测试
这里我们需要测试的是在HUE界面中进行HBase查询。在使用HBase时,如果登录HUE时使用的是admin身份,admin会伪装成hue用户发起命令,所以需要使用hbase的超级用户hbase去给hue赋权,才可以使其具备权限,才可以在HUE界面进行HBase查询:
kdestroy
kinit cdh-master/admin
kadmin > addprinc hbase/test@DOMAIN.COM
kinit hbase/test@DOMAIN.COM
hbase shell
hbase shell > grant 'hue','RWXCA'
Sqoop on HUE功能测试
在Hue界面进行操作,添加sqoop1作业:
sqoop list-databases --connect jdbc:mysql://${MYSQL_SERVER_FQDN}:3306 --username ${MYSQL_USERNAME} --password ${MYSQL_PASSWD}
sqoop import --connect jdbc:mysql://${MYSQL_SERVER_FQDN}:3306/cm --username ${MYSQL_USERNAME} --password ${MYSQL_PASSWD} --table HOSTS --target-dir /user/admin/tgt -m 1 --delete-target-dir
如何在HUE中提交作业,这里不进行复述。
遇到的问题
Q: kerberos ticket renewer 服务报:Ticket expired while renewing credentials
。
A: 这是因为TGT的ticketkrbtgt/DOMAIN.COM@DOMAIN.COM
的renewlife
被设置成了0,这一点可以通过kadmin => getprinc krbtgt/DOMAIN.COM@DOMAIN.COM
看出来。将krbtgt/DOMAIN.COM@DOMAIN.COM
的renewlife
修改为 7d 即可,方法:
modprinc -maxrenewlife 1week krbtgt/DOMAIN.COM@DOMAIN.COM
Q: 提交Spark作业时报错:Delegation Token can be issued only with kerberos or web authentication
。
A: 提交spark作业的时候需要指定
spark master = yarn
mode = cluster
Q: Beeline报错,Failed to find any Kerberos tgt
。
A: 因为sudo权限下生成的credetial不能用于非sudo权限下的beeline,也就是说不要在申请ticket的时候使用sudo,在执行beeline的时候使用非sudo。