Step by Step 实现基于 Cloudera 5.8.2 的企业级安全大数据平台 - Kerberos的整合

Kerberos简介

之前在阿里,非常担心的一件事就是如果有人拿到了hdfs超级管理员帐号,直接把数据rm -rf怎么办?有了Kerberos,就可以轻松防止这样的事情发生。Kerberos 协议实现了比“质询-响应”模式协议更高的安全性:第一,在身份验证过程中,所有的数据都使用不同的密码进行加密,避免了相关验证信息的泄漏;第二,客户端和服务器会相互验证对方的身份,避免了 中间人攻击 ;第三,客户端和服务器间的时间差被严格限制,避免了 回放攻击 。与 WINDOWS 系统中的 用户安全令牌 类似, Kerberos 服务通过“ 加密的票据(防止篡改) ”验证用户身份和提供用户访问权限; Kerberos 服务可以通过使用 会话密钥 确保在会话中数据的机密性和完整性。

Kerberos相关术语

术语 简述
KDC 在启用 Kerberos 的环境中,KDC 用于验证各个模块
Kerberos KDC Server KDC 所在的机器
Kerberos Client 任何一个需要通过 KDC 认证的机器(或模块)
Principal 用于验证一个用户或者一个 Service 的唯一的标识,相当于一个账号,需要为其设置密码(这个密码也被称之为 Key)
Keytab 包含有一个或多个 Principal 以及其密码的文件
Relam 由 KDC 以及多个 Kerberos Client 组成的网络
KDC Admin Account KDC 中拥有管理权限的账户(例如添加、修改、删除Principal)
Authentication Server (AS) 用于初始化认证,并生成 Ticket Granting Ticket (TGT)
Ticket Granting Server (TGS) 在 TGT 的基础上生成 Service Ticket。一般情况下 AS 和 TGS 都在 KDC 的 Server 上

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 文件。

Step by Step 实现基于 Cloudera 5.8.2 的企业级安全大数据平台 - Kerberos的整合_第1张图片
图示: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

假设list_krb_clients文件如下:

192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.5
192.168.1.6
192.168.1.7
192.168.1.8
192.168.1.9
192.168.1.10
192.168.1.11
192.168.1.12
192.168.1.13
192.168.1.14
192.168.1.15
192.168.1.16
192.168.1.17

JDK安装

此过程网上太多教程,不复述。

Kerberos安装

在192.168.1.1上安装服务端:

sudo yum install krb5-server openldap-clients -y

在192.168.1.[2-17]上安装客户端:

sudo pssh -h list_krb_clients -P -l admin -A "sudo yum install krb5-devel krb5-workstation -y"

修改配置

修改krb5.conf,请替换DOMAIN.COM为自定义域名:

[logging] 
default = FILE:/var/log/krb5libs.log 
kdc = FILE:/var/log/krb5kdc.log 
admin_server = FILE:/var/log/kadmind.log

[libdefaults] 
default_realm = DOMAIN.COM 
dns_lookup_realm = false 
dns_lookup_kdc = false 
ticket_lifetime = 24h 
renew_lifetime = 7d 
forwardable = true

[realms] 
DOMAIN.COM = { 
    kdc = 192.168.1.1
    admin_server = 192.168.1.1 
}

[domain_realm] 
.domain.com = DOMAIN.COM 
domain.com = DOMAIN.COM

分发krb5.conf至所有client:

pscp -h list_krb_clients krb5.conf /tmp
pssh -h list_krb_clients "sudo cp /tmp/krb5.conf /etc"

修改服务端192.168.1.1上的配置文件/var/kerberos/krb5kdc/kdc.conf

[kdcdefaults] 
kdc_ports = 88 
kdc_tcp_ports = 88 

[realms] 
DOMAIN.COM = { 
    master_key_type = aes256-cts 
    acl_file = /var/kerberos/krb5kdc/kadm5.acl 
    dict_file = /usr/share/dict/words 
    admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab 
    supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal 
    max_life = 25h 
    max_renewable_life = 8d 
}

修改服务端192.168.1.1上的配置文件/var/kerberos/krb5kdc/kadm5.acl,以允许具备匹配条件的admin用户进行远程登录权限:

*/[email protected] *

由于要支持Java的aes256-cts算法,需要Server和Client都安装JCE,在192.168.1.1上执行:

sudo wget http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip
sudo unzip jce_policy-8.zip
sudo mv UnlimitedJCEPolicyJDK8/*.jar $JAVA_HOME/jre/lib/security 
pscp -h list_krb_clients $JAVA_HOME/jre/lib/security/US_export_policy.jar /tmp 
pscp -h list_krb_clients $JAVA_HOME/jre/lib/security/local_policy.jar /tmp 
pssh -h list -l admin -A "sudo cp /tmp/US_export_policy.jar $JAVA_HOME/jre/lib/security/" 
pssh -h list -l admin -A "sudo cp /tmp/local_policy.jar $JAVA_HOME/jre/lib/security/"

创建Kerberos数据库

在192.168.1.1上对数据库进行初始化,默认的数据库路径为/var/kerberos/krb5kdc,如果需要重建数据库,将该目录下的principal相关的文件删除即可,请牢记数据库密码。

sudo kdb5_util create -r DOMAIN.COM -s

启动Kerberos服务

在192.168.1.1上执行:

# 启动服务命令
sudo /bin/systemctl start krb5kdc 
sudo /bin/systemctl start kadmin
# 加入开机启动项
sudo /bin/systemctl enable krb5kdc
sudo /bin/systemctl enable kadmin

创建Kerberos管理员principal

# 需要设置两次密码 
kadmin.local -q "addprinc cdh-master/admin"

principal的名字的第二部分是admin,那么根据之前配置的acl文件,该principal就拥有administrative privileges,这个账号将会被CDH用来生成其他用户/服务的principal。注意需要先kinit保证已经有principal缓存。Kerberos客户端支持两种,一是使用 principal + Password,二是使用 principal + keytab,前者适合用户进行交互式应用,例如hadoop fs -ls这种,后者适合服务,例如yarn的rm、nm等。

Cloudera整合Kerberos

在此之前,请确保以下前序工作完成:

  • KDC已经安装好并且正在运行
  • 将KDC配置为允许renewable tickets with non-zerolifetime,我们在之前修改kdc.conf文件的时候已经添加了max_lifemax_renewable_life这个2个属性,前者表示服务端允许的Service ticket最大生命周期,后者表示服务端允许的Service ticket更新周期。这2个属性必须分别大于等于客户端对应的配置ticket_lifetimerenew_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/[email protected]` 进行更新,也无济于事。
  • 在Cloudera Manager Server上安装openldap-clients;
  • 为Cloudera Manager创建了超级管理员principal,使其能够有权限在KDC中创建其他的principals;

再次确认完毕后进入如下步骤:

  1. 进入 Cloudera Manager Admin Console 界面并且点击 cluster 右边的按钮选择Enable Kerberos
  2. 点击 Continue,进入下一页进行配置,要注意的是:这里的 Kerberos Encryption Types 必须跟KDC实际支持的加密类型匹配(即kdc.conf中的值),这里使用了默认的aes256-cts,注意,这里的 Kerberos Encryption Types 必须和/etc/krb5.conf中的default_tgs_enctypesdefault_tkt_enctypespermitted_enctypes三个选项的值对应起来,不然会出现集群服务无法认证通过的情况!
  3. 点击 Continue,进入下一页,这一页中不勾选 Manage krb5.conf through Cloudera Manager ,否则会修改掉之前配置的acl,造成 enable kerberos 失败;
  4. 点击 Continue,进入下一页,输入 Cloudera Manager Principal 的管理员账号和密码,注意输入账号的时候要使用@前要使用全称,本文使用的是cdh-master/[email protected]
  5. 点击 Continue,进入下一页,导入 KDC Account Manager Credentials
  6. 点击 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 /[email protected]"

在客户端192.168.1.2上新建principal:

kinit cdh-master/[email protected]
kadmin -q "addprinc /[email protected]"

销毁ticket缓存:

kdestroy

查看当前ticket缓存,这时应会报错No credentials cache found (ticket cache FILE:/tmp/krb5cc_0)

klist -f

重新获取ticket:

kinit /[email protected]

查看当前ticket缓存,应该不会报错:

klist -f

Hive功能测试

CLI测试,首先进行principal初始化

kadmin -q "addprinc hive/[email protected]"
kinit hive/[email protected]

在没有配置 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/[email protected] 
kinit hbase/[email protected] 
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/[email protected]renewlife被设置成了0,这一点可以通过kadmin => getprinc krbtgt/[email protected]看出来。将krbtgt/[email protected]renewlife修改为 7d 即可,方法:

modprinc -maxrenewlife 1week krbtgt/[email protected]

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;

你可能感兴趣的:(Step by Step 实现基于 Cloudera 5.8.2 的企业级安全大数据平台 - Kerberos的整合)