说明
本文描述问题及解决方法同样适用于 弹性 MapReduce(EMR)。
背景
Kerberos是由麻省理工(MIT)开发,对三方进行验证鉴权的服务安全管理系统。该系统很好的体现了西方三权分立的思想,其名字也很形象,来源于希腊神话地狱三个脑袋的看门狗。
- 系统环境说明
Linux环境:centos7.4
CDH:5.16.1
Java:1.8.0_131
Kerberos版本:1.15.1
1)Kerberos部署
1. 安装
cdh01.ali.aiwaystack.com作为Kerberos主节点安装服务:
代码语言:javascript复制yum install krb5-server -y
其他子节点安装krb5-devel、krb5-workstation :
代码语言:javascript复制yum install krb5-devel krb5-workstation -y
2. 修改配置文件
kdc服务器包含三个配置文件:
代码语言:javascript复制# 集群上所有节点都有这个文件而且内容同步
/etc/krb5.conf
# 主服务器上的kdc配置
/var/kerberos/krb5kdc/kdc.conf
# 能够不直接访问 KDC 控制台而从 Kerberos 数据库添加和删除主体,需要添加配置
/var/kerberos/krb5kdc/kadm5.acl
修改/etc/krb5.conf
代码语言:javascript复制# Configuration snippets may be placed in this directory as well
includedir /etc/krb5.conf.d/
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
default_realm = CDH.AI.COM
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 86400
renew_lifetime = 604800
forwardable = true
rdns = false
pkinit_anchors = /etc/pki/tls/certs/ca-bundle.crt
[realms]
CDH.AI.COM = {
kdc = cdh01.ali.aiwaystack.com
admin_server = cdh01.ali.aiwaystack.com
default_domain = cdh01.ali.aiwaystack.com
}
[domain_realm]
.cdh.ai.com = CDH.AI.COM
cdh.ai.com = CDH.AI.COM
配置项说明:
代码语言:javascript复制[logging]:日志输出设置
[libdefaults]:连接的默认配置
default_realm:Kerberos应用程序的默认领域,所有的principal都将带有这个领域标志
ticket_lifetime: 表明凭证生效的时限,一般为24小时
renew_lifetime: 表明凭证最长可以被延期的时限,一般为一个礼拜。当凭证过期之后,对安全认证的服务的后续访问则会失败
clockskew:时钟偏差是不完全符合主机系统时钟的票据时戳的容差,超过此容差将不接受此票据。通常,将时钟扭斜设置为 300 秒(5 分钟)。这意味着从服务器的角度看,票证的时间戳与它的偏差可以是在前后 5 分钟内
udp_preference_limit= 1:禁止使用 udp 可以防止一个 Hadoop 中的错误
[realms]:列举使用的 realm
kdc:代表要 kdc 的位置。格式是 机器:端口
admin_server:代表 admin 的位置。格式是 机器:端口
default_domain:代表默认的域名
[domain_realm]:域名到realm的关系
修改/var/kerberos/krb5kdc/kdc.conf
代码语言:javascript复制[kdcdefaults]
kdc_ports = 88
kdc_tcp_ports = 88
[realms]
CDH.AI.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 camellia256-cts:normal camellia128-cts:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal
}
配置项说明:
代码语言:javascript复制[kdcdefaults]:kdc相关配置,这里只设置了端口信息
[realms]:realms的配置
CDH.AI.COM:设定的realms领域
master_key_type:和 supported_enctypes 默认使用 aes256-cts。JAVA 使用 aes256-cts 验证方式需要安装 JCE 包
acl_file:标注了 admin 的用户权限,文件格式是:Kerberos_principal permissions [target_principal] [restrictions]
supported_enctypes:支持的校验方式
admin_keytab:KDC 进行校验的 keytab
安装JCE包:
安装JCE包需要到Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for JDK/JRE 8这个网址下载,解压之后到目录:
代码语言:javascript复制$JAVA_HOME/jre/lib/security
创建/var/kerberos/krb5kdc/kadm5.acl,内容为:
代码语言:javascript复制*/admin@CDH.AI.COM *
配置文件详细的说明参考官网
3. 创建Kerberos数据库
代码语言:javascript复制# 保存路径为/var/kerberos/krb5kdc 如果需要重建数据库,将该目录下的principal相关的文件删除即可
kdb5_util create -r CDH.AI.COM -s
-r指定配置的realm领域名
出现 Loading random data 的时候另开个终端执行点消耗CPU的命令如 cat /dev/vda > /dev/urandom 可以加快随机数采集
该命令会在 /var/kerberos/krb5kdc/ 目录下创建 principal 数据库。
4. 启动服务
代码语言:javascript复制chkconfig --level 35 krb5kdc on
chkconfig --level 35 kadmin on
systemctl start krb5kdc
systemctl start kadmin
5. 创建Kerberos管理员
代码语言:javascript复制# 需要设置两次密码,当前设置为root
kadmin.local -q "addprinc admin/admin"
principal的名字的第二部分是admin,那么该principal就拥有administrative privileges
这个账号将会被CDH用来生成其他用户/服务的principal
6. 测试Kerberos
代码语言:javascript复制# 列出Kerberos中的所有认证用户,即principals
kadmin.local -q "list_principals"
# 添加认证用户,需要输入密码
kadmin.local -q "addprinc dy"
# 使用该用户登录,获取身份认证,需要输入密码
kinit dy
# 查看当前用户的认证信息ticket
klist
# 更新ticket
kinit -R
# 销毁当前的ticket
kdestroy
# 删除认证用户
kadmin.local -q "delprinc dy"
抽取密钥并将其储存在本地 keytab 文件 /etc/krb5.keytab 中。这个文件由超级用户拥有,所以必须是 root 用户才能在 kadmin shell 中执行以下命令:
代码语言:javascript复制kadmin.local -q "ktadd kadmin/admin"
# 查看生成的keytab
klist -k /etc/krb5.keytab
2)CDH集成Kerberos
1. 为 Cloudera Manager Server获取或创建Kerberos主体
为了能在集群中创建和部署host principals和keytabs,Cloudera Manager Server必须有一个Kerberos principal来创建其他的账户。
如果一个principal的名字的第二部分是admin(例如, cloudera-scm/admin@CDH.AI.COM),那么该principal就拥有administrative privileges。
在KDC server主机上,创建一个名为[cloudra-scm]的principal,并为其设置密码。执行命令:
代码语言:javascript复制[root@cdh01 ~]# kadmin.local
Authenticating as principal root/admin@CDH.AI.COM with password.
Kadmin.local: addprinc -pw admin cloudera-scm/admin@CDH.AI.COM
WARNING: no policy specified for cloudera-scm/admin@CDH.AI.COM; defaulting to no policy
Principal "cloudera-scm/admin@CDH.AI.COM" created.
输入listprincs可以看到创建了一个名为cloudera-scm/admin@CDH.AI.COM的principal:
2. 导入KDC Account Manager凭据
1. 在 Cloudera Manager Admin Console 中,选择:
管理 > 安全 > Kerberos凭据 > 导入 Kerberos Account Manager 凭据
2. 在导入 Kerberos Account Manager 凭据对话框中,针对可以在 KDC 中为 CDH 群集创建主体的用户输入用户名和密码。
重点:用户名中,“/”前后都属于用户名部分,“/”及后面的admin都不可省略,否则会验证不通过。
3. 在cloudera Manager Admin Console中配置Kerberos默认领域
1. 在 Cloudera Manager Admin Console 中,选择:
管理 > 安全 > Kerberos凭据 > 配置
2. 单击Kerberos类别,然后在 Kerberos 安全领域字段中为群集输入您在 krb5.conf 文件中配置的 Kerberos 领域、KDC Server主机、Kerberos加密类型
此处仅贴出有改动部分:
3. 单击保存更改
4. 停止所有服务
1. 在主页上,单机集群名称右侧的下拉,停止所有服务。
2. 在主页上,单击 Cloudera Management Service 右侧的下拉,选择停止。
5. 启用 HDFS安全性
1. 点击主页上的HDFS,选择配置
2. 修改下面参数
代码语言:javascript复制hadoop.security.authentication ---> kerberos
hadoop.security.authorization ---> true
dfs.datanode.data.dir.perm ---> 700
dfs.datanode.address ---> 1004
dfs.datanode.http.address ---> 1006
3. 单击保存更改
6. 启用HBASE安全性
1. 点击主页上的HBASE,选择配置
2. 修改下面参数
代码语言:javascript复制hbase.security.authentication ---> Kerberos
hbase.security.authorization ---> true
3. 单击保存
7. 启用kafka安全性
1. 单击主页上的kafka,选择配置
2. 修改下面参数
代码语言:javascript复制kerberos.auth.enable ---> true
security.inter.broker.protocol ---> SASL_PLAINTEXT
3. 单击保存
8. kafka使用SASL验证
kafka目前支持的机制有GSSAPI(Kerberos)和PLAIN ,在以上步骤中,Kafka brokers的SASL已配置,接下来配置Kafka客户端
1. 生成jaas文件
客户端(生产者,消费者,connect,等等)用自己的principal认证集群(通常用相同名称作为运行客户端的用户)。因此,获取或根据需要创建这些principal。然后,为每个principal创建一个JAAS文件,KafkaClient描述了生产者和消费者客户端如何连接到broker。下面是一个客户端使用keytab的配置例子(建议长时间运行的进程)。
在/etc/kafka/目录下创建kafka_client_jaas.conf文件:
代码语言:javascript复制KafkaClient {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
keyTab="/etc/kafka/conf/kafka_client.keytab"
principal="dy/kafka@CDH.AI.COM";
};
创建dy/kafka@CDH.AI.COM
代码语言:javascript复制kadmin: addprinc -randkey dy/kafka@CDH.AI.COM
kadmin: xst -k /etc/kafka/conf/kafka_client.keytab dy/kafka@CDH.AI.COM
在使用producer和consumer java接口时,要在代码main方法中,加入
代码语言:javascript复制System.setProperty(“java.security.auth.login.config”,”/etc/kafka/kafka_client_jaas.conf”);
保证程序可以读取到jaas文件。
在producer和consumer的config里加入
代码语言:javascript复制props.put("sasl.kerberos.service.name", "kafka");
props.put("sasl.mechanism", " GSSAPI");
props.put("security.protocol", "SASL_PLAINTEXT");
对于java程序配置到以上步骤就可以了,以下步骤可以跳过。
对于命令行工具,比如kafka-console-consumer 或 kafka-console-producer,kinit连同 “useTicketCache=true”使用,如:
代码语言:javascript复制KafkaClient {
com.sun.security.auth.module.Krb5LoginModule required
useTicketCache=true;
};
2. 通过JAAS作为JVM参数(每个客户端的JVM)
在/opt/cloudera/parcels/KAFKA/lib/kafka/bin/kafka-run-class.sh文件中JVM performance options参数的KAFKA_JVM_PERFORMANCE_OPTS中加入
代码语言:javascript复制-Djava.security.auth.login.config=/etc/kafka/kafka_client_jaas.conf
3. 生成producer.properties和consumer.properties文件
在/etc/kafka/conf/目录下生成producer.properties和consumer.properties
代码语言:javascript复制security.protocol=SASL_PLAINTEXT (or SASL_SSL)
sasl.mechanism=GSSAPI
sasl.kerberos.service.name=kafka
4. 使用命令行工具进行生产消费
部署kerberos后,要使用新生产者:
代码语言:javascript复制kafka-console-producer --broker-list 10.100.11.1:9092 –topic test --producer.config config/producer.properties
新消费者:
代码语言:javascript复制kafka-console-consumer --bootstrap-server 10.100.11.1:9092 --topic test --new-consumer --from-beginning --consumer.config config/consumer.properties
9. 启用zookeeper安全性
1. 单击主页上的zookeeper,选择配置
2. 修改下面参数
代码语言:javascript复制enableSecurity ---> true
10. 等待“生成凭据”命令完成
在 Cloudera Manager 中为任何服务启用安全保护之后,将自动触发称为“生成凭据”的命令。您可以在显示正在运行的命令的屏幕右上角看到该命令的进度。请等待此命令完成(通过内含“0”的灰色框表示)。
11. 使 Hue 能够使用 Cloudera Manager 与 Hadoop 安全一起工作
如果您使用的是 Hue 服务,那么您必须向 Hue 服务添加 Kerberos Ticket Renewer 的角色实例,以使 Hue 能够使用 Cloudera Manager 与安全的 Hadoop 群集一起正常工作,否则集群会持续报致命错误。
Hue Kerberos Ticket Renewer 仅为主体 hue/<hostname>@HADOOP.COM续订 Hue 服务的票证。然后,将使用该 Hue 主体为 Hue 内的应用程序(如 Job Browser、File Browser 等)模拟其他用户。其他服务(如 HDFS 和 MapReduce)不使用 Hue Kerberos Ticket Renewer。它们将在启动时获取票证,并使用这些票证获取各种访问权限的委派令牌。每个服务根据需要处理自己的票证续订。
1. 转到Hue服务。
2. 单击实例选项卡。
3. 单击添加角色实例按钮。
4. 为与Hue Server相同的主机分配Kerberos Ticket Renewer序角色实例。
5. 在向导完成后,状态将显示已完成,并且 Kerberos Ticket Renewer 角色实例已配置。Hue 服务现在将与安全的 Hadoop 群集一起工作。
注:此处可能会报Couldn't renew kerberos ticket的错误
代码语言:javascript复制[10/Feb/2020 23:41:17 -0800] kt_renewer INFO Renewing kerberos ticket to work around kerberos 1.8.1: /bin/kinit -R -c /var/run/hue/hue_krb5_ccache
[10/Feb/2020 23:41:17 -0800] kt_renewer ERROR Couldn't renew kerberos ticket in order to work around Kerberos 1.8.1 issue. Please check that the ticket for 'hue/cdh02.ali.aiwaystack.com@CDH.AI.COM' is still renewable:
$ klist -f -c /var/run/hue/hue_krb5_ccache
If the 'renew until' date is the same as the 'valid starting' date, the ticket cannot be renewed. Please check your KDC configuration, and the ticket renewal policy (maxrenewlife) for the 'hue/cdh02.ali.aiwaystack.com@CDH.AI.COM' and `krbtgt' principals.
[11/Feb/2020 15:44:19 ] settings INFO Welcome to Hue 3.9.0
[10/Feb/2020 23:44:21 -0800] __init__ INFO Couldn't import snappy. Support for snappy compression disabled.
[10/Feb/2020 23:44:21 -0800] kt_renewer INFO Reinitting kerberos retry attempt 0 from keytab /bin/kinit -k -t /opt/cloudera-manager/cm-5.16.1/run/cloudera-scm-agent/process/1297-hue-KT_RENEWER/hue.keytab -c /var/run/hue/hue_krb5_ccache hue/cdh02.ali.aiwaystack.com@CDH.AI.COM
[10/Feb/2020 23:44:22 -0800] kt_renewer INFO Renewing kerberos ticket to work around kerberos 1.8.1: /bin/kinit -R -c /var/run/hue/hue_krb5_ccache
[10/Feb/2020 23:44:22 -0800] kt_renewer ERROR Couldn't renew kerberos ticket in order to work around Kerberos 1.8.1 issue. Please check that the ticket for 'hue/cdh02.ali.aiwaystack.com@CDH.AI.COM' is still renewable:
$ klist -f -c /var/run/hue/hue_krb5_ccache
If the 'renew until' date is the same as the 'valid starting' date, the ticket cannot be renewed. Please check your KDC configuration, and the ticket renewal policy (maxrenewlife) for the 'hue/cdh02.ali.aiwaystack.com@CDH.AI.COM' and `krbtgt' principals.
[11/Feb/2020 15:44:24 ] settings INFO Welcome to Hue 3.9.0
[10/Feb/2020 23:44:26 -0800] __init__ INFO Couldn't import snappy. Support for snappy compression disabled.
[10/Feb/2020 23:44:26 -0800] kt_renewer INFO Reinitting kerberos retry attempt 0 from keytab /bin/kinit -k -t /opt/cloudera-manager/cm-5.16.1/run/cloudera-scm-agent/process/1297-hue-KT_RENEWER/hue.keytab -c /var/run/hue/hue_krb5_ccache hue/cdh02.ali.aiwaystack.com@CDH.AI.COM
[10/Feb/2020 23:44:28 -0800] kt_renewer INFO Renewing kerberos ticket to work around kerberos 1.8.1: /bin/kinit -R -c /var/run/hue/hue_krb5_ccache
[10/Feb/2020 23:44:28 -0800] kt_renewer ERROR Couldn't renew kerberos ticket in order to work around Kerberos 1.8.1 issue. Please check that the ticket for 'hue/cdh02.ali.aiwaystack.com@CDH.AI.COM' is still renewable:
$ klist -f -c /var/run/hue/hue_krb5_ccache
If the 'renew until' date is the same as the 'valid starting' date, the ticket cannot be renewed. Please check your KDC configuration, and the ticket renewal policy (maxrenewlife) for the 'hue/cdh02.ali.aiwaystack.com@CDH.AI.COM' and `krbtgt' principals.
此问题官方给出了解决方案:
即:
代码语言:javascript复制root@cdh01 ~
> # kadmin.local
Authenticating as principal root/admin@CDH.AI.COM with password.
kadmin.local: modprinc -maxrenewlife 90day krbtgt/CDH.AI.COM@CDH.AI.COM
Principal "krbtgt/CDH.AI.COM@CDH.AI.COM" modified.
kadmin.local: modprinc -maxrenewlife 90day allow_renewable hue/cdh02.ali.aiwaystack.com@CDH.AI.COM
Principal "hue/cdh02.ali.aiwaystack.com@CDH.AI.COM" modified.
12. 启动所有服务
启动所有服务,在主页上,单击群集名称右侧的 并选择启动。
启动 Cloudera Management Service,在主页上,单击Cloudera Management Service右侧的下拉并选择启动。
13. 部署客户端配置
在主页,单击群集名称右侧的下拉,并选择部署客户端配置。
14. 创建 HDFS 超级用户主体
要为用户创建主目录,您需要对超级用户帐户具有访问权限。在 HDFS 中,运行 NameNode 进程的用户帐户(默认情况下为 hdfds)是一个超级用户。在安装 CDH 的过程中,CDH 会自动在每个群集主机上创建 hdfs 超级用户帐户。当为 HDFS 服务启用 Kerberos 时,您无法通过 su - hdfs 命令访问 hdfs 超级用户帐户。要在 Kerberos 处于启用状态时能够访问 hdfs 超级用户帐户,您必须创建一个 Kerberos 主体或 AD 用户,并且其第一个或唯一一个组成部分必须是 hdfs。或者,您也可以指定其成员属于超级用户的超级用户组。
在kadmin.local中,键入以下命令来创建名为hdfs的Kerberos主体:
代码语言:javascript复制root@cdh01 ~
> # kadmin.local
Authenticating as principal root/admin@CDH.AI.COM with password.
kadmin.local: addprinc hdfs@CDH.AI.COM
WARNING: no policy specified for hdfs@CDH.AI.COM; defaulting to no policy
Enter password for principal "hdfs@CDH.AI.COM":
Re-enter password for principal "hdfs@CDH.AI.COM":
Principal "hdfs@CDH.AI.COM" created.
此命令会提示您为 hdfs 主体创建密码。请使用强密码,因为此主体对 HDFS 中的所有文件提供超级用户访问权限。
要作为 hdfs 超级用户运行命令,您必须为 hdfs 主体获取 Kerberos 凭据。要执行此操作,请运行以下命令并提供密码:
代码语言:javascript复制root@cdh01 ~
> # kinit hdfs@CDH.AI.COM