CDH5.13 集成Kerberos配置

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:

CDH5.13 集成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. 参考

CDH集成Kerberos配置

【原创】大叔经验分享(30)CM开启kerberos

如何在Redhat7.3的CDH5.14中启用Kerberos

(完)

上一篇:Cas客户端源码解析


下一篇:【转】还款计划文件生成