版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。
http://www.itdecent.cn/p/b606602d3ada
一、概述
本文是針對(duì)cloudera大數(shù)據(jù)集群安全部署整理的文檔,主要介紹了大數(shù)據(jù)集群Kerberos服務(wù)器部署和集成的過(guò)程。
這篇文章介紹了kerberos配置高可用HA的過(guò)程:Kerberos高可用HA配置
二、環(huán)境說(shuō)明
1、主機(jī)名
主機(jī)名首字母必須為小寫,否則在集成kerberos時(shí)會(huì)出現(xiàn)很多異常問(wèn)題。
2、hosts文件
/etc/hosts文件中不要包含127.0.0.1的解析。
3、ASE-256加密
我們的系統(tǒng)是Red Hat Enterprise Linux Server
release 7.5,對(duì)于centos5.6及以上的系統(tǒng),默認(rèn)使用AES-256來(lái)加密的。無(wú)論采用何種加密方式,zookeeper都必須要求集群中所有節(jié)點(diǎn)安裝java Cryptography Extension(JCE) Unlimited Strength Jurisdiction Policy File。否則會(huì)報(bào)錯(cuò):
Failed to authenticate using SASL
javax.security.sasl.SaslException:GSS initiate failed 【Caused by GSSException:Failure unspecified at GSS-API level (Mechanism level:Encryption type AES256 CTS mode with HMAC SHA1-96 is not supported/enabled)】...
該文件解壓后,是兩個(gè)jar包,local_policy.jar和US_export_policy.jar,默認(rèn)的jdk自帶的這兩個(gè)文件是強(qiáng)度加密的,不能滿足要求,需要替換掉,在官網(wǎng)上下載非限制強(qiáng)度加密的這兩個(gè)文件,并放在/usr/java/jdk1.8.0_121/jre/lib/security路徑下。
說(shuō)明:也可以不使用AES-256加密方式,本文后續(xù)采用的是AES-128-cts方式。
三、Kerberos服務(wù)器(KDC)安裝
1、為所有節(jié)點(diǎn)安裝kerberos軟件包:

2、選擇Cloudera Manager節(jié)點(diǎn)作為KDC服務(wù)器,安裝額外包:

3、KDC服務(wù)器涉及到三個(gè)配置文件,/etc/krb5.conf、/var/kerberos/krb5kdc/kdc.conf和/var/kerberos/krb5kdc/kadm5.acl。
注意:這三個(gè)文件的配置已通過(guò)數(shù)十遍的測(cè)試驗(yàn)證,每個(gè)參數(shù)都不能隨意修改?。。?/b>
編輯/etc/krb5.conf,這是客戶端上的配置,需要同步到每個(gè)客戶端節(jié)點(diǎn)上。修改其中的realm以及對(duì)應(yīng)的kdc/kadmin服務(wù)器地址。
[root@host1 bin]# cat/ 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 = SPDB.COM
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
[realms]
SPDB.COM = {
? kdc= host1
admin_server = host1
? }
[domain_realm]
.spdb.com = SPDB.COM
spdb.com = SPDB.COM
[kdc]
profile=/var/kerberos/krb5kdc/kdc.conf
編輯/var/kerberos/krb5kdc/kdc.conf,這是Kerberos服務(wù)器的配置,修改其中的配置文件中的realm名稱。
[root@host1 bin]# cat /var/kerberos/krb5kdc/kdc.conf
[kdcdefaults]
kdc_ports = 88
kdc_tcp_ports = 88
[realms]
SPDB.COM = {
max_renewable_life = 7d
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 camellia256-cts:normal? camellia128-cts:normal des-hmac-sha1:normal? des-cbc-md5:normal des-cbc-crc:normal
}
編輯/var/kerberos/krb5kdc/kadm5.acl,添加作為管理員的類型,這里以/admin結(jié)尾的用戶是作為管理員用戶。
*/admin@SPDB.COM? ? ? *
4、完成文件配置后,通過(guò)命令初始化KDC Database。該命令會(huì)在/var/kerberos/krb5kdc/目錄下創(chuàng)建principal數(shù)據(jù)庫(kù)。

5、然后啟動(dòng)KDC進(jìn)程,并加入開機(jī)啟動(dòng)項(xiàng)

6、使用Kadmin給Cloudera Manager建立Kerberos賬戶。

7、將KDC Server上的krb5.conf文件拷貝到所有Kerberos客戶端

四、CDH集群?jiǎn)⒂胟erberos
1、進(jìn)入Cloudera Manager的“管理”—>“安全”界面,選擇啟用“kerberos”


2、填寫基本配置信息,選擇MIT KDC,加密類型輸入aes128-cts,kerberos安全領(lǐng)域輸入SPDB.COM,KDC Server和KDC Admin Server Host都填寫CM主機(jī)名


3、前置條件,全部勾選,點(diǎn)擊繼續(xù)

4、點(diǎn)擊繼續(xù),不勾選讓cloudera
Manager來(lái)管理krb5.conf,點(diǎn)擊繼續(xù)
5、輸入cloudera Manager的kerberos管理員賬號(hào),必須和之前創(chuàng)建的賬號(hào)一致:cloudera-scm/admin,點(diǎn)擊繼續(xù)


6、配置對(duì)應(yīng)服務(wù)使用的principal名稱,這里用默認(rèn)的就可以,點(diǎn)擊繼續(xù)

7、配置HDFS需要的端口,使用默認(rèn)就可以,然后點(diǎn)擊可以重啟集群(“Yes, I am ready…”部分),點(diǎn)擊繼續(xù)。

8、等待集群重啟完成

9、至此已成功啟用kerberos

五、Kafka額外配置及驗(yàn)證(kafka集成kerberos)
CDH集群在啟用了kerberos后,kafka還需要做額外的配置,否則啟動(dòng)會(huì)報(bào)如下錯(cuò):
19/06/19 19:27:22 WARNzookeeper.ClientCnxn: SASL configuration failed:
javax.security.auth.login.LoginException:No JAAS configuration section named 'Client' was found in specified JAASconfiguration file: '/tmp/wk/kafka/jaas-keytab.conf'. Will continue connectionto Zookeeper server without SASL authentication, if Zookeeper server allows it.
19/06/19 19:27:22 INFOzookeeper.ClientCnxn: Opening socket connection to server
localhost/127.0.0.1:2181
19/06/19 19:27:22 ERRORzookeeper.ZooKeeperClient: [ZooKeeperClient] Auth failed.
1、Server端
在CDH集群?jiǎn)⒂胟erberos后,CM默認(rèn)會(huì)將ssl.client.auth配置為none并Enable Kerberos Authentication,但除此之外,kafka還有一項(xiàng)需要額外配置,在CM上修改security.inter.broker.protocol為SASL_PLAINTEXT,再重啟kafka服務(wù)。
2、Client端
需要分別創(chuàng)建三個(gè)文件,jaas.conf、client.properties和jaas-keytab.conf
創(chuàng)建jaas.conf文件,內(nèi)容如下:
[root@host1 kafka]# cat jaas.conf
KafkaClient{
com.sun.security.auth.module.Krb5LoginModule
required
useTicketCache=true;
};
創(chuàng)建client.properties文件,內(nèi)容如下:
[root@host1 kafka]# client.properties
KafkaClient{
com.sun.security.auth.module.Krb5LoginModule
required
useTicketCache=true;
};
[root@host1 kafka]# cat client.properties
security.protocol=SASL_PLAINTEXT
sasl.kerberos.service.name=kafka
創(chuàng)建jaas-keytab.conf文件,內(nèi)容如下:
[root@host1 kafka]# cat jaas-keytab.conf
KafkaClient{
? com.sun.security.auth.module.Krb5LoginModule
required
? useKeyTab=true
? keyTab="/root/hdfs.keytab"
? principal="hdfs@SPDB.COM";
};
之后進(jìn)行認(rèn)證,認(rèn)證有兩種方式,一種是通過(guò)kinit username,另一種是通過(guò)keytab文件。
第一種:
exportKAFKA_OPTS="-Djava.security.auth.login.config=/tmp/wk/kafka/jaas.conf"
第二種:
exportKAFKA_OPTS="-Djava.security.auth.login.config=/tmp/wk/kafka/jaas-keytab.conf"
兩種都可以。
測(cè)試Producer
[root@host1 kafka]# kafka-console-producer --broker-list 172.29.X.X:9092 --topic test --producer.config
client.properties
19/06/20 09:23:07 INFOutils.Log4jControllerRegistration$: Registered kafka:type=kafka.Log4jControllerMBean
19/06/20 09:23:07 INFOproducer.ProducerConfig: ProducerConfig values:
? ? ? ? acks= 1
? ? ? ? batch.size= 16384
? ? ? ? bootstrap.servers= [172.29.X.X:9092]
? ? ? ? buffer.memory= 33554432
? ? ? ? client.id= console-producer
? ? ? ? compression.type= none
? ? ? ? connections.max.idle.ms= 540000
? ? ? ? enable.idempotence= false
? ? ? ? interceptor.classes= []
? ? ? ? key.serializer= class org.apache.kafka.common.serialization.ByteArraySerializer
? ? ? ? linger.ms= 1000
? ? ? ? max.block.ms= 60000
? ? ? ? max.in.flight.requests.per.connection= 5
? ? ? ? max.request.size= 1048576
? ? ? ? metadata.max.age.ms= 300000
? ? ? ? metric.reporters= []
? ? ? ? metrics.num.samples= 2
? ? ? ? metrics.recording.level= INFO
? ? ? ? metrics.sample.window.ms= 30000
? ? ? ? partitioner.class= class org.apache.kafka.clients.producer.internals.DefaultPartitioner
? ? ? ? receive.buffer.bytes= 32768
? ? ? ? reconnect.backoff.max.ms= 1000
? ? ? ? reconnect.backoff.ms= 50
? ? ? ? request.timeout.ms= 1500
? ? ? ? retries= 3
? ? ? ? retry.backoff.ms= 100
? ? ? ? sasl.client.callback.handler.class= null
? ? ? ? sasl.jaas.config= null
? ? ? ? sasl.kerberos.kinit.cmd= /usr/bin/kinit
? ? ? ? sasl.kerberos.min.time.before.relogin= 60000
? ? ? ? sasl.kerberos.service.name= kafka
? ? ? ? sasl.kerberos.ticket.renew.jitter= 0.05
? ? ? ? sasl.kerberos.ticket.renew.window.factor= 0.8
? ? ? ? sasl.login.callback.handler.class= null
? ? ? ? sasl.login.class= null
? ? ? ? sasl.login.refresh.buffer.seconds= 300
? ? ? ? sasl.login.refresh.min.period.seconds= 60
? ? ? ? sasl.login.refresh.window.factor= 0.8
? ? ? ? sasl.login.refresh.window.jitter= 0.05
? ? ? ? sasl.mechanism= GSSAPI
? ? ? ? security.protocol= SASL_PLAINTEXT
? ? ? ? send.buffer.bytes= 102400
? ? ? ? ssl.cipher.suites= null
? ? ? ? ssl.enabled.protocols= [TLSv1.2, TLSv1.1, TLSv1]
? ? ? ? ssl.endpoint.identification.algorithm= null
? ? ? ? ssl.key.password= null
? ? ? ? ssl.keymanager.algorithm= SunX509
? ? ? ? ssl.keystore.location= null
? ? ? ? ssl.keystore.password= null
? ? ? ? ssl.keystore.type= JKS
? ? ? ? ssl.protocol= TLS
? ? ? ? ssl.provider= null
? ? ? ? ssl.secure.random.implementation= null
? ? ? ? ssl.trustmanager.algorithm= PKIX
? ? ? ? ssl.truststore.location= null
? ? ? ? ssl.truststore.password= null
? ? ? ? ssl.truststore.type= JKS
? ? ? ? transaction.timeout.ms= 60000
? ? ? ? transactional.id= null
? ? ? ? value.serializer= class org.apache.kafka.common.serialization.ByteArraySerializer
19/06/20 09:23:07 INFOauthenticator.AbstractLogin: Successfully logged in.
19/06/20 09:23:07 INFOkerberos.KerberosLogin: [Principal=null]: TGT refresh thread started.
19/06/20 09:23:07 INFOkerberos.KerberosLogin: [Principal=null]: TGT valid starting at: Thu Jun 2009:20:41 CST 2019
19/06/20 09:23:07 INFOkerberos.KerberosLogin: [Principal=null]: TGT expires: Fri Jun 21 09:20:41 CST2019
19/06/20 09:23:07 INFOkerberos.KerberosLogin: [Principal=null]: TGT refresh sleeping until: Fri Jun21 05:43:42 CST 2019
19/06/20 09:23:07 INFO utils.AppInfoParser:Kafka version : 2.0.0-cdh6.1.1
19/06/20 09:23:07 INFO utils.AppInfoParser:Kafka commitId : unknown
>Hello World!
19/06/20 09:23:29 INFO clients.Metadata:Cluster ID: 8JBaORpCR5evbE0EjF8SrA
>Hello
Kerberos!
>quit;
啟動(dòng)producer客戶端過(guò)程和發(fā)消息過(guò)程沒報(bào)錯(cuò)即代表producer客戶端配置成功。
測(cè)試Consumer
[root@host1 kafka]#kafka-console-consumer --topic test --from-beginning --bootstrap-server 172.29.X.X:9092 --consumer.config client.properties
19/06/20 09:34:02 INFOutils.Log4jControllerRegistration$: Registered kafka:type=kafka.Log4jControllerMBean
19/06/20 09:34:03 INFOconsumer.ConsumerConfig: ConsumerConfig values:
? ? ? ? auto.commit.interval.ms= 5000
? ? ? ? auto.offset.reset= earliest
? ? ? ? bootstrap.servers= [172.29.91.117:9092]
? ? ? ? check.crcs= true
? ? ? ? client.id=
? ? ? ? connections.max.idle.ms= 540000
? ? ? ? default.api.timeout.ms= 60000
? ? ? ? enable.auto.commit= true
? ? ? ? exclude.internal.topics= true
? ? ? ? fetch.max.bytes= 52428800
? ? ? ? fetch.max.wait.ms= 500
? ? ? ? fetch.min.bytes= 1
? ? ? ? group.id= console-consumer-26237
? ? ? ? heartbeat.interval.ms= 3000
? ? ? ? interceptor.classes= []
? ? ? ? internal.leave.group.on.close= true
? ? ? ? isolation.level= read_uncommitted
? ? ? ? key.deserializer= class org.apache.kafka.common.serialization.ByteArrayDeserializer
? ? ? ? max.partition.fetch.bytes= 1048576
? ? ? ? max.poll.interval.ms= 300000
? ? ? ? max.poll.records= 500
? ? ? ? metadata.max.age.ms= 300000
? ? ? ? metric.reporters= []
? ? ? ? metrics.num.samples= 2
? ? ? ? metrics.recording.level= INFO
? ? ? ? metrics.sample.window.ms= 30000
? ? ? ? partition.assignment.strategy= [class org.apache.kafka.clients.consumer.RangeAssignor]
? ? ? ? receive.buffer.bytes= 65536
? ? ? ? reconnect.backoff.max.ms= 1000
? ? ? ? reconnect.backoff.ms= 50
? ? ? ? request.timeout.ms= 30000
? ? ? ? retry.backoff.ms= 100
? ? ? ? sasl.client.callback.handler.class= null
? ? ? ? sasl.jaas.config= null
? ? ? ? sasl.kerberos.kinit.cmd= /usr/bin/kinit
? ? ? ? sasl.kerberos.min.time.before.relogin= 60000
? ? ? ? sasl.kerberos.service.name= kafka
? ? ? ? sasl.kerberos.ticket.renew.jitter= 0.05
? ? ? ? sasl.kerberos.ticket.renew.window.factor= 0.8
? ? ? ? sasl.login.callback.handler.class= null
? ? ? ? sasl.login.class= null
? ? ? ? sasl.login.refresh.buffer.seconds= 300
? ? ? ? sasl.login.refresh.min.period.seconds= 60
? ? ? ? sasl.login.refresh.window.factor= 0.8
? ? ? ? sasl.login.refresh.window.jitter= 0.05
? ? ? ? sasl.mechanism= GSSAPI
? ? ? ? security.protocol= SASL_PLAINTEXT
? ? ? ? send.buffer.bytes= 131072
? ? ? ? session.timeout.ms= 10000
? ? ? ? ssl.cipher.suites= null
? ? ? ? ssl.enabled.protocols= [TLSv1.2, TLSv1.1, TLSv1]
? ? ? ? ssl.endpoint.identification.algorithm= null
? ? ? ? ssl.key.password= null
? ? ? ? ssl.keymanager.algorithm= SunX509
? ? ? ? ssl.keystore.location= null
? ? ? ? ssl.keystore.password= null
? ? ? ? ssl.keystore.type= JKS
? ? ? ? ssl.protocol= TLS
? ? ? ? ssl.provider= null
? ? ? ? ssl.secure.random.implementation= null
? ? ? ? ssl.trustmanager.algorithm= PKIX
? ? ? ? ssl.truststore.location= null
? ? ? ? ssl.truststore.password= null
? ? ? ? ssl.truststore.type= JKS
? ? ? ? value.deserializer= class org.apache.kafka.common.serialization.ByteArrayDeserializer
19/06/20 09:34:03 INFOauthenticator.AbstractLogin: Successfully logged in.
19/06/20 09:34:03 INFOkerberos.KerberosLogin: [Principal=null]: TGT refresh thread started.
19/06/20 09:34:03 INFO kerberos.KerberosLogin:[Principal=null]: TGT valid starting at: Thu Jun 20 09:20:41 CST 2019
19/06/20 09:34:03 INFOkerberos.KerberosLogin: [Principal=null]: TGT expires: Fri Jun 21 09:20:41 CST2019
19/06/20 09:34:03 INFOkerberos.KerberosLogin: [Principal=null]: TGT refresh sleeping until: Fri Jun21 05:01:47 CST 2019
19/06/20 09:34:03 INFO utils.AppInfoParser:Kafka version : 2.0.0-cdh6.1.1
19/06/20 09:34:03 INFO utils.AppInfoParser:Kafka commitId : unknown
19/06/20 09:34:03 INFO clients.Metadata:Cluster ID: 8JBaORpCR5evbE0EjF8SrA
19/06/20 09:34:04 INFOinternals.AbstractCoordinator: [Consumer clientId=consumer-1,groupId=console-consumer-26237] Discovered group coordinator wgqcasappun06:9092(id: 2147483459 rack: null)
19/06/20 09:34:04 INFO internals.ConsumerCoordinator:[Consumer clientId=consumer-1, groupId=console-consumer-26237] Revokingpreviously assigned partitions []
19/06/20 09:34:04 INFOinternals.AbstractCoordinator: [Consumer clientId=consumer-1,groupId=console-consumer-26237] (Re-)joining group
19/06/20 09:34:04 INFOinternals.AbstractCoordinator: [Consumer clientId=consumer-1,groupId=console-consumer-26237] Group coordinator wgqcasappun06:9092 (id:2147483459 rack: null) is unavailable or invalid, will attempt rediscovery
19/06/20 09:34:04 INFOinternals.AbstractCoordinator: [Consumer clientId=consumer-1,groupId=console-consumer-26237] Discovered group coordinator wgqcasappun06:9092(id: 2147483459 rack: null)
19/06/20 09:34:04 INFOinternals.AbstractCoordinator: [Consumer clientId=consumer-1, groupId=console-consumer-26237](Re-)joining group
19/06/20 09:34:04 INFOinternals.AbstractCoordinator: [Consumer clientId=consumer-1,groupId=console-consumer-26237] (Re-)joining group
19/06/20 09:34:04 INFOinternals.AbstractCoordinator: [Consumer clientId=consumer-1,groupId=console-consumer-26237] (Re-)joining group
19/06/20 09:34:04 INFOinternals.AbstractCoordinator: [Consumer clientId=consumer-1,groupId=console-consumer-26237] (Re-)joining group
19/06/20 09:34:05 INFOinternals.AbstractCoordinator: [Consumer clientId=consumer-1,groupId=console-consumer-26237] (Re-)joining group
19/06/20 09:34:05 INFOinternals.AbstractCoordinator: [Consumer clientId=consumer-1,groupId=console-consumer-26237] (Re-)joining group
19/06/20 09:34:05 INFO internals.AbstractCoordinator:[Consumer clientId=consumer-1, groupId=console-consumer-26237] (Re-)joininggroup
19/06/20 09:34:08 INFOinternals.AbstractCoordinator: [Consumer clientId=consumer-1,groupId=console-consumer-26237] Successfully joined group with generation 1
19/06/20 09:34:08 INFOinternals.ConsumerCoordinator: [Consumer clientId=consumer-1,groupId=console-consumer-26237] Setting newly assigned partitions [test-0]
19/06/20 09:34:08 INFO internals.Fetcher:[Consumer clientId=consumer-1, groupId=console-consumer-26237] Resetting offsetfor partition test-0 to offset 0.
Hello World!
Hello Kerberos!
quit
啟動(dòng)consumer客戶端過(guò)程和接受消息過(guò)程沒報(bào)錯(cuò)即代表客戶端配置成功。
六、Kerberos使用
使用wangkuan用戶訪問(wèn)HDFS及運(yùn)行MapReduce。
1、訪問(wèn)HDFS
沒有登錄kerberos會(huì)報(bào)“Client cannot authenticate via:[TOKEN, KERBEROS]”授權(quán)失敗

使用wangkuan用戶登錄kerberos,沒有報(bào)錯(cuò)就說(shuō)明登錄成功

再次訪問(wèn)則通過(guò)

2、運(yùn)行MapReduce
沒有登錄kerberos會(huì)報(bào)“Client cannot authenticate via:[TOKEN, KERBEROS]”授權(quán)失敗

使用wangkuan用戶登錄kerberos,沒有報(bào)錯(cuò)就說(shuō)明登錄成功

再次訪問(wèn)則通過(guò)

Kafka的配置及驗(yàn)證過(guò)程見第5章。