CDH集成Kerberos

一、安装Kerberos
1. 整体说明
软件版本 
操作系统:CentOs 6.8 
CDH版本:Hadoop 2.6.0-cdh5.9.0 
JDK版本:jdk1.7.0_67-cloudera 
运行用户:root

集群主机角色划分 
sunmvm20 作为master节点,安装kerberos Server 
其他节点作为slave节点,安装kerberos client

2. 配置host
添加主机名到 /etc/hosts 文件中。

$ cat /etc/hosts
127.0.0.1       localhost

192.168.1.20        sunmvm20
192.168.1.26        sunmvm26
192.168.1.27        sunmvm27
192.168.1.28        sunmvm28

注意:hostname 请使用小写,要不然在集成 kerberos 时会出现一些错误。

3. 安装 Kerberos

在 sunmvm20 上安装 krb5、krb5-server 和 krb5-client。

yum install krb5-server -y
# klist等命令找不大时执行下面安装
yum install -y krb5-server krb5-workstation pam_krb5

在其他节点安装 krb5-devel、krb5-workstation

$ ssh sunmvm26 "yum install krb5-devel krb5-workstation -y"
$ ssh sunmvm27 "yum install krb5-devel krb5-workstation -y"
$ ssh sunmvm28 "yum install krb5-devel krb5-workstation -y"

4. 修改配置文件
kdc 服务涉及到三个配置文件:

/etc/krb5.conf
/var/kerberos/krb5kdc/kdc.conf
/var/kerberos/krb5kdc/kadm5.acl
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 = 0HKJ.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]
0HKJ.COM = {
  kdc = sunmvm20
  admin_server = sunmvm20
 }

[domain_realm]
 .0hkj.com = 0HKJ.COM
ohkj.com = 0HKJ.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]:可以设定一些针对特定应用的配置,覆盖默认配置。
2)修改 /var/kerberos/krb5kdc/kdc.conf ,该文件包含 Kerberos 的配置信息。例如,KDC 的位置,Kerbero 的 admin 的realms 等。需要所有使用的 Kerberos 的机器上的配置文件都同步。这里仅列举需要的基本配置。详细介绍参考:krb5conf
 

[kdcdefaults]
 kdc_ports = 88
 kdc_tcp_ports = 88

[realms]
 0HKJ.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
 }

说明:

0HKJ.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。 
关于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的加密方式错误。

3)为了能够不直接访问 KDC 控制台而从 Kerberos 数据库添加和删除主体,请对 Kerberos 管理服务器指示允许哪些主体执行哪些操作。通过创建 /var/lib/kerberos/krb5kdc/kadm5.acl 完成此操作。
$ cat /var/kerberos/krb5kdc/kadm5.acl

内容如下:

*/[email protected] *

表示principal的名字的第二部分如果是admin,那么该principal就拥有管理员权限

5. 同步配置文件

将 kdc 中的 /etc/krb5.conf 拷贝到集群中其他服务器即可。

$ scp /etc/krb5.conf sunmvm26:/etc/krb5.conf
$ scp /etc/krb5.conf sunmvm27:/etc/krb5.conf
$ scp /etc/krb5.conf sunmvm28:/etc/krb5.conf

6. 创建数据库

在 sunmvm20 上运行初始化数据库命令。其中 -r 指定对应 realm。

$ kdb5_util create -r 0HKJ.COM -s

7. 启动Kerberos服务

在 sunmvm20 节点上运行:

$ chkconfig --level 35 krb5kdc on
$ chkconfig --level 35 kadmin on
$ service krb5kdc start
$ service kadmin start

8. 创建 kerberos 管理员
关于 kerberos 的管理,可以使用 kadmin.local 或 kadmin,至于使用哪个,取决于账户和访问权限:

如果有访问 kdc 服务器的 root 权限,但是没有 kerberos admin 账户,使用 kadmin.local
如果没有访问 kdc 服务器的 root 权限,但是用 kerberos admin 账户,使用 kadmin 
在 sunmvm20 上创建远程管理的管理员:

手动输入两次密码
$ kadmin.local -q "addprinc root/admin"

  • 也可以不用手动输入密码

$ echo -e "root\nroot" | 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

9. 测试 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"

Cloudera Manager 添加 Kerberos
在此之前,请确保以下前序工作完成:

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/[email protected] 进行更新,也无济于事。

在Cloudera Manager Server上安装openldap-clients

为Cloudera Manager创建了超级管理员principal,使其能够有权限在KDC中创建其他的principals,如上面创建的cloudera-scm;
再次确认完毕后进入如下步骤:

1.启用Kerberos
è¿éåå¾çæè¿°

2.确认完成启用Kerberos前的准备

è¿éåå¾çæè¿°

3.KDC信息

è¿éåå¾çæè¿°

要注意的是:这里的 Kerberos Encryption Types 必须跟KDC实际支持的加密类型匹配(即kdc.conf中的值)

4.KDB5信息

è¿éåå¾çæè¿°

5.KDC Account Manager

这里写图片描述

6.导入KDC Account Manager 凭据

è¿éåå¾çæè¿°

7.Kerberos Principals

这里写图片描述

8.Set HDFS Port

è¿éåå¾çæè¿°

9.重启服务

è¿éåå¾çæè¿°

之后 Cloudera Manager 会自动重启集群服务,启动之后会提示 Kerberos 已启用。在 Cloudera Manager 上启用 Kerberos 的过程中,会自动做以下的事情:

集群中有多少个节点,每个账户就会生成对应个数的 principal ;
为每个对应的 principal 创建 keytab;
部署 keytab 文件到指定的节点中;
在每个服务的配置文件中加入有关 Kerberos 的配置;
启用之后访问集群的所有资源都需要使用相应的账号来访问,否则会无法通过 Kerberos 的 authenticatin。

除此之外,对于特定的服务需要做额外配置,本文只介绍HDFS、YARN、HBase,其余服务请参照官方文档自行进行配置。 
 

此时直接用CM生成的principal访问HDFS会失败,因为那些自动生成的principal的密码是随机的,用户并不知道而通过命令行的方式访问HDFS需要先使用kinit来登录并获得ticket 
所以使用kinit hdfs/[email protected]需要输入密码的时候无法继续

用户可以通过创建一个[email protected]的principal并记住密码从命令行中访问HDFS
[root@master ~]# kadmin.local -q "addprinc hdfs"
[root@master ~]# kinit hdfs 
[root@master ~]# hdfs dfs -ls
Found 4 items
drwxr-xr-x   - hdfs supergroup          0 2017-08-29 12:00 .Trash
drwx------   - hdfs supergroup          0 2017-08-29 10:49 .staging
drwxr-xr-x   - hdfs supergroup          0 2017-08-29 10:35 QuasiMonteCarlo_1503974105326_258590930
drwxr-xr-x   - hdfs supergroup          0 2017-08-29 10:35 QuasiMonteCarlo_1503974128088_828012046

遇到的问题

hdfs用户提交mr作业无法运行

# kinit hdfs
# hadoop jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/hadoop-mapreduce-examples.jar pi 10 100

异常信息1:

Diagnostics: Application application_1504017397148_0002 initialization failed (exitCode=255) with output: main : command provided 0
main : run as user is hdfs
main : requested yarn user is hdfs
Requested user hdfs is not whitelisted and has id 986,which is below the minimum allowed 1000
 

原因: 
Linux user 的 user id 要大于等于1000,否则会无法提交Job 
例如,如果以hdfs(id为986)的身份提交一个job,就会看到以上的错误信息

解决方法: 
1.使用命令 usermod -u 修改一个用户的user id 
2.修改Clouder关于这个该项的设置,Yarn->配置->min.user.id修改为合适的值(如0),默认为1000


è¿éåå¾çæè¿°

异常信息2:hdfs用户被禁止运行 YARN container

Diagnostics: Application application_1504019347914_0001 initialization failed (exitCode=255) with output: main : command provided 0
main : run as user is hdfs
main : requested yarn user is hdfs
Requested user hdfs is banned

原因: 
yarn的设置中将hdfs用户禁用了

解决方法: 
修改Clouder关于这个该项的设置,Yarn->配置->banned.users 将hdfs用户移除

è¿éåå¾çæè¿°

Beeline/JDBC测试:

# beeline --verbose=true 
beeline > !connect jdbc:hive2://master:10000/default;principal=hive/[email protected];

Error: Could not open client transport with JDBC Uri: jdbc:hive2://master:10000/default;principal=hive/[email protected];: Peer indicated failure: GSS initiate failed (state=08S01,code=0)
java.sql.SQLException: Could not open client transport with JDBC Uri: jdbc:hive2://master:10000/default;principal=hive/[email protected];: Peer indicated failure: GSS initiate failed

Caused by: org.apache.thrift.transport.TTransportException: Peer indicated failure: GSS initiate failed

在使用jdbc+kerberos时,主要注意几个问题

1.链接字符串格式,其中user,password并不生效 
jdbc:hive2://:/;principal= 
比如Connection con = DriverManager.getConnection("jdbc:hive2://host:10000/cdnlog;principal=hdfs/host@KERBEROS_HADOOP", "user1", ""); 
在传入hiveserver2时,用户并不是user1 
2.在有tgt cache时,传入的用户为当前tgt的用户(可以通过klist查看) 
3.principal的名称和hiveserver2的主机名需要一致 
4.For Beeline connection string, it should be "!connect jdbc:hive2://:/;principal=”. Please make sure it is the hive’s principal, not the user’s. And when you kinit, it should be kinit user’s keytab, not the hive’s keytab.
 

# kadmin.local -q "addprinc hive"

# kinit hive

# beeline --verbose=true 
beeline > !connect jdbc:hive2://master:10000/default;principal=hive/[email protected];
scan complete in 4ms
Connecting to jdbc:hive2://master:10000/default;principal=hive/[email protected];
Connected to: Apache Hive (version 1.1.0-cdh5.11.1)
Driver: Hive JDBC (version 1.1.0-cdh5.11.1)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://master:10000/default> 

HUE出错

kinit: Ticket expired while renewing credentials

这是因为krbtgt/[email protected]的[renewlife]被设置成了0,这一点可以通过kadmin.local -q "getprinc krbtgt/[email protected]" 看出来。

将krbtgt/[email protected]的[renewlife]修改为7days即可,方法

1

kadmin.local -q "modprinc -maxrenewlife 1week krbtgt/[email protected]"

你可能感兴趣的:(kerberos)