1. 前言
本文基本上参考自:CDH集成Kerberos配置
增加了一些说明。
1.1. 软件版本
操作系统:Centos 7.5 和 Red Hat Enterprise Linux Server release 7.4
CDH版本:Hadoop 2.6.0-cdh5.13.0
JDK版本:1.8u144
运行用户:root
为什么有两个系统呢?因为先在我们公司的集群尝试了,然后再到客户那边安装。
1.2. 集群角色划分
我们的测试集群命名很简单,每个节点的hostname类似master和slaver1、slaver2……。
一个master节点,安装kerberos Server;
其他节点作为slave节点,安装kerberos client;
cloudera manager server 在的节点,安装openldap-clients。
安装前主机之间是互通的,这个应该安装完cloudera就知道了。
我在master节点写了一个分发执行命令的脚本,类似以下:
#!/usr/bin/bash if [ "$#" == "1" ]; then for num in 2 3 4 5 6 do echo "connecting to slaver${num} and excute commands" ssh root@slaver${num} $1 echo -e "slaver${num} done \n" done else echo "usage: $0 'command'" fi
还有一个分发文件的脚本:
!/usr/bin/bash if [ "$#" == "2" ]; then for num in 2 3 4 5 6 do echo -e "\nscp file $1 to slaver${num}:$2" scp -r $1 root@slaver${num}:$2 done else echo "usage: $0 from_file to_file"
2. 安装kerberos
2.1. 安装krb5-server和krb5-clinent
在master上安装krb5、krb5-server 和 krb5-client。
yum install krb5-server -y # klist等命令找不大时执行下面安装 yum install -y krb5-server krb5-workstation pam_krb
其中,在redhat系统的时候,会出现klist找不到的情况,所以都安装一下免得麻烦;
分发命令,在其他节点安装krb5-devel、krb5-workstation
./bro_command.sh "yum install krb5-devel krb5-workstation -y"
2.2. 修改配置文件
kdc 服务涉及到三个配置文件:
- /etc/krb5.conf
- /var/kerberos/krb5kdc/kdc.conf
- /var/kerberos/krb5kdc/kadm5.acl
2.2.1. 编辑配置文件 /etc/krb5.conf
[logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] default_realm = EXAMPLE.COM dns_lookup_realm = false dns_lookup_kdc = false ticket_lifetime = 24h renew_lifetime = 7d forwardable = true default_tgs_enctypes = aes256-cts-hmac-sha1-96 default_tkt_enctypes = aes256-cts-hmac-sha1-96 permitted_enctypes = aes256-cts-hmac-sha1-96 clockskew = 120 udp_preference_limit = 1 [realms] EXAMPLE.COM = { kdc = master admin_server = master } [domain_realm] .example.com = EXAMPLE.COM example.com = EXAMPLE.COM
说明:
- [logging]:表示 server 端的日志的打印位置
- [libdefaults]:每种连接的默认配置,需要注意以下几个关键的小配置
- default_realm = 0HKJ.COM:设置 Kerberos 应用程序的默认领域。如果您有多个领域,只需向 [realms] 节添加其他的语句。
- ticket_lifetime: 表明凭证生效的时限,一般为24小时。
- renew_lifetime: 表明凭证最长可以被延期的时限,一般为一个礼拜。当凭证过期之后,对安全认证的服务的后续访问则会失败。
- clockskew:时钟偏差是不完全符合主机系统时钟的票据时戳的容差,超过此容差将不接受此票据。通常,将时钟扭斜设置为 300 秒(5 分钟)。这意味着从服务器的角度看,票证的时间戳与它的偏差可以是在前后 5 分钟内。
- udp_preference_limit= 1:禁止使用 udp 可以防止一个 Hadoop 中的错误
- [realms]:列举使用的 realm。
- kdc:代表要 kdc 的位置。格式是 机器:端口
- admin_server:代表 admin 的位置。格式是 机器:端口
- default_domain:代表默认的域名
- [appdefaults]:可以设定一些针对特定应用的配置,覆盖默认配置。
这个相比默认的配置增改了比较多东西,特别是一些默认加密方式的设置:
default_tgs_enctypes = aes256-cts-hmac-sha1-96 default_tkt_enctypes = aes256-cts-hmac-sha1-96 permitted_enctypes = aes256-cts-hmac-sha1-96
加密的东西会有小坑,下面统一讲。
2.2.2. 修改 /var/kerberos/krb5kdc/kdc.conf
该文件包含 Kerberos 的配置信息。例如,KDC 的位置,Kerbero 的 admin 的realms 等。需要所有使用的 Kerberos 的机器上的配置文件都同步。这里仅列举需要的基本配置。详细介绍参考krb5conf部分。
[kdcdefaults] kdc_ports = 88 kdc_tcp_ports = 88 [realms] EXAMPLE.COM = { #master_key_type = aes256-cts acl_file = /var/kerberos/krb5kdc/kadm5.acl dict_file = /usr/share/dict/words max_renewable_life = 7d max_life = 1d 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 default_principal_flags = +renewable, +forwardable }
同样修改和增加了一些东西,尤其可以看到default_principal_flags部分,大概是为了解决到hue的定时更新凭证的问题。
- EXAMPLE.COM: 是设定的 realms。名字随意。Kerberos 可以支持多个 realms,会增加复杂度。大小写敏感,一般为了识别使用全部大写。这个 realms 跟机器的 host 没有大关系。
- master_key_type:和 supported_enctypes 默认使用 aes256-cts。JAVA 使用 aes256-cts 验证方式需要安装 JCE 包,见下面的说明。为了简便,你可以不使用 aes256-cts 算法,这样就不需要安装 JCE 。
- acl_file:标注了 admin 的用户权限,需要用户自己创建。文件格式是:Kerberos_principal permissions [target_principal] [restrictions]
- supported_enctypes:支持的校验方式。
- admin_keytab:KDC 进行校验的 keytab。
2.2.3. 关于加密方式
原文中提到了AES-256的一段描述:
对于使用 centos5. 6 及以上的系统,默认使用 AES-256 来加密的。这就需要集群中的所有节点上安装 JCE,如果你使用的是 JDK1.6 ,则到Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for JDK/JRE 6 页面下载,如果是 JDK1.7,则到 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for JDK/JRE 7 下载。下载的文件是一个 zip 包,解开后,将里面的两个文件放到下面的目录中:$JAVA_HOME/jre/lib/security.
上面这一步一定要做,否则会报zk,namenode等不支持默认tkt的加密方式错误。
看了这个,因为我的版本是jdk1.8,所以在$JAVA_HOME/jre/lib/security 路径找了一下,是存在两个jar包的:
- local_policy.jar
- US_export_policy.jar
诡异的是,我两次安装都遇到了编码问题,有一次应该是Activity Monitor 报错:
ERROR Main
Failed to start Firehose
java.lang.RuntimeException: java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.io.IOException: Login failure for hue/$server1@ANYTHING.COM from keytab cmon.keytab
...
Caused by: KrbException: no supported default etypes for default_tkt_enctypes
然后我自己捣鼓了一下,去官网下载了这个包:Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 Download;
然后备份了一下原来jre目录下的文件,用下载的两个包覆盖过去,然后重启krb5-server的两个服务,后面重启又可以了。
所以开不开aes256-cts算法要按照自己的情况去定,而且这个决定跟后面集成到cdh中有联系。
2.2.4. 修改配置/var/kerberos/krb5kdc/kadm5.acl
*/admin@EXAMPLE.COM *
表示principal的名字的第二部分如果是admin,那么该principal就拥有管理员权限。
2.3. 同步配置文件
将master的/etc/krb5.conf分发到其他slaver:
./scp_to_hosts.sh /etc/krb5.conf /etc/krb5.conf
2.4. 创建数据库
在master上运行初始化数据库命令,其中-r 指定对应 realm。
kdb5_util create -r EXAMPLE.COM –s
如果遇到数据库已经存在的提示,可以把 /var/kerberos/krb5kdc/ 目录下的 principal 的相关文件都删除掉。默认的数据库名字都是 principal。可以使用 -d指定数据库名字。
2.5. 启动kerberos服务
# 启动服务: systemctl restart krb5kdc systemctl restart kadmin # 开机自动重启: systemctl enable krb5kdc systemctl enable kadmin
2.6. 创建 kerberos 管理员
关于 kerberos 的管理,可以使用 kadmin.local 或 kadmin,至于使用哪个,取决于账户和访问权限:
如果有访问 kdc 服务器的 root 权限,但是没有 kerberos admin 账户,使用 kadmin.local;
如果没有访问 kdc 服务器的 root 权限,但是用 kerberos admin 账户,使用 kadmin在master上创建远程管理的管理员;
kadmin.local -q "addprinc root/admin"
输入密码。
抽取密钥并将其储存在本地 keytab 文件 /etc/krb5.keytab 中。这个文件由超级用户拥有,所以必须是 root 用户才能在 kadmin shell 中执行以下命令:
kadmin.local -q "ktadd kadmin/admin" # 查看生成的keytab klist -k /etc/krb5.keytab
2.7. 测试kerberos
# 列出Kerberos中的所有认证用户,即principals kadmin.local -q "list_principals" # 添加认证用户,需要输入密码 kadmin.local -q "addprinc user1" # 使用该用户登录,获取身份认证,需要输入密码 kinit user1 # 查看当前用户的认证信息ticket klist # 更新ticket kinit -R # 销毁当前的ticket kdestroy # 删除认证用户 kadmin.local -q "delprinc user1"
2.8. CM节点安装额外组件
在cloudera manager server 所在节点安装额外的组件:
yum -y install openldap-clients
这个在原博客中博主忘记了。
3. Cloudera配置kerboros
3.1. 配置前确认
- KDC已经安装好并且正在运行
- 将KDC配置为允许renewable tickets with non-zerolifetime(在之前修改kdc.conf文件的时候已经添加了kdc_tcp_ports、max_life和max_renewable_life这个三个选项)
- 在Cloudera Manager Server上安装openldap-clients
- 为Cloudera Manager创建一个principal,使其能够有权限在KDC中创建其他的principals,就是上面创建的Kerberos管理员账号
3.2. cloudera配置kerboros
进入Cloudera Manager,集群,操作,启用kerberos:
选择“启用Kerberos”。
确保如下列出的所有检查项都已完成,全部勾选,继续。
点击“继续”,配置相关的KDC信息,包括类型、KDC服务器、KDC Realm、加密类型以及待创建的Service Principal(hdfs,yarn,,hbase,hive等)的更新生命期等。
我的例子中,
KDC类型:MIT KDC
kerberos安全领域:EXAMPLE.COM
KDC server主机:master
KDC Admin Server Host: master
这个界面有个选项,kerboros加密类型,需要和KDC实际支持的加密类型匹配即 /etc/krb5.conf 中的default_tgs_enctypes、default_tkt_enctypes和permitted_enctypes三个选项的值对应起来,不然会出现集群服务无法认证通过的情况。
填 aes256-cts 继续。
KRB5配置,不建议让Cloudera Manager来管理krb5.conf, 不勾选,点击“继续”。
KDC Account Manager 凭据,输入Cloudera Manager的Kerbers管理员账号,一定得和之前创建的账号一致,点击“继续”。
Kerberos主体,默认就好,继续。
配置端口,勾选准备好重启集群,继续。
集群重启完成,点击“继续”。
点击“继续”,点击“完成”,至此已成功启用Kerberos。
不过一般不会那么顺利的了,我大部分遇到的是加密算法的问题。
4. 其他
4.1. 在CM上启用Kerberos的过程中,CM自动执行的事情
4.1.1. 生成账号对应的principle
集群中有多少个节点,每个账户都会生成对应个数的principal,格式为username/hostname@EXAMPLE.COM,例如hdfs/slaver1@EXAMPLE.COM。使用如下命令来查看:
kadmin.local -q "list_principals"
4.1.2. 为每个对应的principal创建keytab
4.1.3. 部署keytab文件到指定的节点中
keytab是包含principals和加密principal key的文件,keytab文件对于每个host是唯一的,因为key中包含hostname,keytab文件用于不需要人工交互和保存纯文本密码,实现到kerberos上验证一个主机上的principal。启用之后访问集群的所有资源都需要使用相应的账号来访问,否则会无法通过Kerberos的authenticatin
4.1.4.在每个服务的配置文件中加入有关Kerberos的配置
其中包括Zookeeper服务所需要的jaas.conf和keytab文件都会自动设定并读取,如果用户仍然手动修改了Zookeeper的服务,要确保这两个文件的路径和内容正确性。
4.2. 创建HDFS超级用户
此时直接用CM生成的principal访问HDFS会失败,因为那些自动生成的principal的密码是随机的,用户并不知道,而通过命令行的方式访问HDFS需要先使用kinit来登录并获得ticket,所以使用kinit hdfs/slaver1@EXAMPLE 需要输入密码的时候无法继续。用户可以通过创建一个hdfs@EXAMPLE.COM的principal并记住密码从命令行中访问HDFS。登录之后就可以通过认证并访问HDFS,默认hdfs用户是超级用户。
kadmin.local -q "addprinc hdfs" kinit hdfs@EXAMPLE.COM
4.3. 为每个用户创建principal
当集群运行Kerberos后,每一个Hadoop user都必须有一个principal或者keytab来获取Kerberos credentials(即使用密码的方式或者使用keytab验证的方式)这样才能访问集群并使用Hadoop的服务。也就是说,如果Hadoop集群存在一个名为hdfs@EXAMPLE.COM的principal那么在集群的每一个节点上应该存在一个名为hdfs的Linux用户。同时,在HDFS中的目录/user要存在相应的用户目录(即/user/hdfs),且该目录的owner和group都要是hdfs
一般来说,Hadoop user会对应集群中的每个服务,即一个服务对应一个user。例如impala服务对应用户impala。
至此,集群上的服务都启用了Kerberos的安全认证。
4.4. 验证Kerberos在集群上是否正常工作
4.4.1.确认HDFS可以正常使用
登录到某一个节点后,切换到hdfs用户,然后用kinit来获取credentials
现在用hadoop hdfs -ls /应该能正常输出结果
用kdestroy销毁credentials后,再使用hadoop hdfs -ls /会发现报错。
4.4.2. 确认可以正常提交MapReduce job
获取了hdfs的证书后,提交一个PI程序,如果能正常提交并成功运行,则说明Kerberized Hadoop cluster在正常工作。
hadoop jar /opt/cloudera/parcels/CDH-5.9.0-1.cdh5.9.0.p0.23/lib/hadoop-mapreduce/hadoop-mapreduce-examples-2.6.0-cdh5.9.0.jar pi 2 2
5. 预留坑位
6. 参考
如何在Redhat7.3的CDH5.14中启用Kerberos
(完)