一、背景
在我們部署完kafka之后,雖然我們已經可以“肆意”的用kafka了,但是在一個大公司的實際生產環境中,kafka集群往往十分龐大,每個使用者都應該只關心自己所負責的Topic,並且對其他人所使用的Topic沒有權限。這樣一來可以將資源隔離開來,二來可以防止誤操作。
在權限控制之前,我們必須要啟用的就是用戶認證,沒有用戶,自然沒有權限一說了。
二、kafka啟用kerberos認證
2.1 在KDC中添加kafka用戶,並生成keytab
新建kfaka用戶 |
kadmin.local -q 'addprinc -randkey kafka/{hostname}@{REALM}' |
生成keytab |
kadmin.local -q "ktadd -k /etc/security/keytabs/{keytabname}.keytab kafka/{hostname}@{REALM}" |
注意:
1、如果之前zookeeper沒有啟用kerberos,這里也要啟用zookeeper的kerberos
2、如果之前在CM中啟用了kerberos,我們可以直接從CM中獲取keytab,但是注意keytab一定要保持最新的,否則認證不會通過,keytab的位置是:
/var/run/cloudera-scm-agent/process/****-kafka-KAFKA_BROKER/kafka.keytab
/var/run/cloudera-scm-agent/process/****-zookeeper-server/zookeeper.keytab
2.2 修改server.properties
//修改這一句 listeners=SASL_PLAINTEXT://host.name:port //新增以下 authorizer.class.name = kafka.security.auth.SimpleAclAuthorizer security.inter.broker.protocol=SASL_PLAINTEXT sasl.mechanism.inter.broker.protocol=GSSAPI sasl.enabled.mechanisms=GSSAPI sasl.kerberos.service.name=kafka super.users=User:kafka |
2.3 新建kafka_server.jaass
KafkaServer { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true serviceName="kafka" keyTab="/etc/keytab/kafka_122.keytab" //替換為自己的keytab所在位置 principal="kafka/{hostname}@{REALM}";//替換為自己的keytab所對應principle };
// Zookeeper client authentication,因為卡夫卡使用過程中會和zookeeper進行交互 Client { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true serviceName="zookeeper" keyTab="/etc/keytab/kafka_122.keytab" //替換為自己的keytab所在位置 principal="kafka/{hostname}@{REALM}";//替換為自己的keytab所對應principle }; |
2.4 修改啟動腳本
export KAFKA_OPTS="-Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.auth.login.config=/root/kafka/config/kafka_server.jaas" //剛才的kafka_server.jaas位置 |
2.5重啟broker
bin/kafka-server-stop.sh bin/kafka-server-start.sh |
2.6 客戶端啟用kerberos
在broker啟用kerberos之后,如果我們后續需要在命令行界面進行操作,及consumer與producer操作,我們需要在這些客戶端也配置上kerberos
2.6.1新增kafka_client.jaas
KafkaClient { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true keyTab="/etc/keytab/kafka_122.keytab" serviceName="kafka" principal="kafka/{hostname}@{REALM}"; };
// Zookeeper client authentication Client { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true serviceName="zookeeper" keyTab="/etc/keytab/kafka_122.keytab" principal="kafka/{hostname}@{REALM}"; };
|
2.6.2配置生效
當前會話生效: export KAFKA_OPTS="-Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.auth.login.config=/opt/kafka/config/kafka_client.jaas" |
配置到環境變量中 vim /etc/profile 增加 export KAFKA_OPTS="-Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.auth.login.config=/opt/kafka/config/kafka_client.jaas" |
2.6.3若有用到consumer或者producer,在consumer.properties或producer.properties中增加
security.protocol=SASL_PLAINTEXT sasl.mechanism=GSSAPI sasl.kerberos.service.name=kafka |
三、kafka啟用acl
Kafka認證管理CLI(和其他的CLI腳本)可以在bin目錄中找到。CLI腳本名是kafka-acls.sh。啟用之前,需要在server.properties里添加這句:
allow.everyone.if.no.acl.found=false |
四、MirrorMaker的跨域同步
4.1 修改kerberos配置
添加互信principle |
kadmin.local下操作 addprinc krbtgt/{REALMA}@{REALMB} addprinc krbtgt/{REALMB}@{REALMA} |
修改krb5.conf |
[realms]//realms 里配上兩個域的信息 HADOOP.SPADE.COM = { kdc = hb21-bd-cm-130-61:88 admin_server = hb21-bd-cm-130-61:749 } HADOOP.TEST.COM = { kdc = tk-dba-hadoop-152:88 admin_server = tk-dba-hadoop-152:749 } [domain_realm] //domain_realm 配上域名和主機名的映射,有多少機器就要配多少 tk-dba-hadoop-154 = HADOOP.TEST.COM hb21-dba-kfk-130-120 = HADOOP.SPADE.COM
[capaths] //capaths 配上互信的域的映射 HADOOP.SAPDE.COM ={ HADOOP.TEST.COM = . } HADOOP.TEST.COM={ HADOOP.SPADE.COM = . }
|
4.2 修改broker配置
添加sasl.kerberos.principal.to.local.rules屬性
sasl.kerberos.principal.to.local.rules=RULE:[1:$1@$0](.*@\HADOOP.TEST.COM$)s/@\HADOOP.TEST.COM$//,RULE:[2:$1@$0](.*@\HADOOP.TEST.COM$)s/@\HADOOP.TEST.COM$//,RULE:[1:$1@$0](.*@\HADOOP.SPADE.COM$)s/@\HADOOP.SPADE.COM$//,RULE:[2:$1@$0](.*@\HADOOP.SPADE.COM$)s/@\HADOOP.SPADE.COM$//,DEFAULT |
4.3 驗證互信是否成功
從域B中復制出keytab到域A的機器中,然后在A中使用該keytab,配置jaas文件,導入環境變量中。用該keytab操作集群A或者集群B中的topic,能正常寫入數據即為成功。
五、啟用kerberos之后的平滑過度期
生產環境啟用kerberos之后,為了給業務向的consumer和producer一個平滑的接入認證系統的緩沖時間,這段時間我們可以給kafka啟用兩個監聽端口,一個是需要kerberos認證的端口,一個不需要認證的端口。讓他們共同存在,同時服務。
5.1 增加監聽端口
修改server.properties |
listeners=SASL_PLAINTEXT://10.21.130.120:9092,PLAINTEXT://10.21.130.120:9093 allow.everyone.if.no.acl.found=false |
5.2 添加ANONYMOUS用戶的訪問權限
bin/kafka-acls.sh --add --authorizer-properties zookeeper.connect={host:port/childpath} --allow-principal User:ANONYMOUS --allow-host * --operation All --topic {topicname} |
5.3 測試不同認證方式共存成功與否
刪除jaas環境變量 |
unset {變量名} |
producer測試 |
bin/kafka-console-producer.sh --broker-list {host}:9093 --topic{topicname} |
六、啟用zookeeper的acl同步
kafka的bin目錄下的zookeeper-security-migration.sh,可以將kafka的權限,遍歷賦給zookeeper中每個子節點,然后分別設置acl,因為zookeeper的acl是僅對當前節點生效,對其下節點不生效的,單獨賦權限很麻煩。zookeeper-security-migration.sh解決了這個問題。
修改server.properties,增加 zookeeper.set.acl=true |
重啟kafka集群(批量重啟或滾動重啟) |
啟動zookeeper-security-migration.sh腳本,secure設置同步,unsecure取消同步 bin/zookeeper-security-migration --zookeeper.acl=secure --zookeeper.connect={host}:{port}/{path} |