kafka集羣安全化之啓用kerberos與acl

一、背景

在我們部署完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,這裏也要啓用zookeeperkerberos

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(參考http://orchome.com/185)

Kafka認證管理CLI(和其他的CLI腳本)可以在bin目錄中找到。CLI腳本名是kafka-acls.sh。啓用之前,需要在server.properties裏添加這句:

 

allow.everyone.if.no.acl.found=false

 

以下列出了所有腳本支持的選項:

選項

描述

默認

類型選擇

--add

添加一個acl

 

Action

--remove

移除一個acl

 

Action

--list

列出acl

 

Action

--authorizer

authorizer的完全限定類名

kafka.security.auth.SimpleAclAuthorizer

Configuration

--authorizer-properties

key=val,傳給authorizer進行初始化,例如:zookeeper.connect=localhost:2181

 

Configuration

--cluster

指定集羣作爲資源。

 

Resource

--topic [topic-name]

指定topic作爲資源。

 

Resource

--group [group-name]

指定 consumer-group 作爲資源。

 

Resource

-allow-principal

添加到允許訪問的ACL中,Principal是PrincipalType:name格式。
你可以指定多個。

 

Principal

--deny-principal

添加到拒絕訪問的ACL中,Principal是PrincipalType:name格式。
你可以指定多個。

 

Principal

--allow-host

--allow-principal中的principal的IP地址允許訪問。

如果--allow-principal指定的默認值是*,則意味着指定“所有主機”

Host

--deny-host

允許或拒絕的操作。
有效值爲:讀,寫,創建,刪除,更改,描述,ClusterAction,全部

ALL

Operation

--operation

--deny-principal中的principals的IP地址拒絕訪問。

如果 --deny-principal指定的默認值是 * 則意味着指定 "所有主機"

Host

--producer

爲producer角色添加/刪除acl。生成acl,允許在topic上WRITE, DESCRIBE和CREATE集羣。

 

Convenience

--consumer

爲consumer role添加/刪除acl,生成acl,允許在topic上READ, DESCRIBE 和 consumer-group上READ。

 

Convenience

--force

假設所有操作都是yes,規避提示

 

Convenience



常用命令舉例:因爲kafka的acl信息是存在zookeeper上的,所以需要提供zookeeper.connect參數,並且acl的存在與否與資源的存在與否無關。

最後的資源可以是topic,也可是cluster,也可以是consumer-group

給Bob和Alice從198.168.159.0(1)對test讀寫的權限

bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:Bob --allow-principal User:Alice --allow-host 198.168.159.0 --allow-host 198.168.159.1 --operation Read --operation Write --topic test

只拒絕BadBob從198.168.159.3對test的讀權限

bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:* --allow-host * --deny-principal User:BadBob --deny-host 198.168.159.3 --operation Read --topic test

列出test的所有權限

bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --list --topic test

刪除權限

bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --remove --allow-principal User:* --allow-host * --deny-principal User:BadBob --deny-host 198.168.159.3 --operation Read --topic test

給生產者Bob對test的生產權限

bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:Bob --producer --topic test

給消費者Bob對test的消費權限

bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:Bob --consumer --topic test --group Group-1

 

 

四、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}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章