Kafka ACL實現架構以及實操案例剖析

ITPUB社群發表於2023-02-20

1、方案設計

基本原則:不接入外部儲存,基於kafka原生ACL認證

環境:kafka-2.2.1、zookeeper-3.6.3

kafka給我們提供了SASL/SCRAM模式,將SASL、ACL規則資訊儲存到zookeeper中,並且透過KafkaClientAdmin Api可新增、編輯、刪除ACL規則,其特性如下

  • 應用傳送、消費實現動態身份認證和授權 基於kafka SASL/SCRAM模式,客戶端會在建立連線進行SASL身份驗證,在消費傳送時,進行ACL鑑權

  • 安全認證程式碼無侵入性、相容原生kafka api 有兩種配置方式,透過根據-Djava.security.auth.login.config指定jaas配置檔案,並且配置producer.properties/consumer.properties 開啟SASL配置,相容原生kafka api

  • 賬號級別區分:管理賬號有最高許可權、業務賬號限定資源許可權 可透過配置kafka叢集超級管理員,透過超級管理員賬號登入是不進行ACL鑑權。因此超級管理員可以操作所有的資源許可權

  • 安全認證支援動態開啟、關閉 kafka提供SASL和ACL管理的api,透過這些api可以新增、修改、查詢、刪除SASL和ACL策略。透過配置策略,可以實現安全策略開啟、關閉

1.1 客戶端與kafka叢集認證、授權

客戶端與Kafka叢集認證、授權總體工作機制如下圖所示:

Kafka ACL實現架構以及實操案例剖析

安全認證、授權步驟如下:

  • 在叢集初始化時,配置開啟SASL、ACL,包括

    • broker與broker的SASL認證配置
    • broker與zookeeper的SASL認證配置
  • 新增SASL、ACL規則 管理員賬號:新增SASL管理員賬號,管理員賬號新增完成後,broker與broker的認證才會成功。應用賬號:新增主題、消費組時,透過KafkaAdminClient Api新增以alice為使用者名稱,應用scret-1為密碼的SASL認證資訊。並且給這個使用者授予訊息寫入許可權

  • 客戶端配置SASL配置,併傳送訊息 在properties中配置SASL賬號密碼。或者指定jaas配置檔案

  • 服務端認證、鑑權 在客戶端與服務端建立連線時,對客戶端alice進行身份認證(SASL),認證透過後,在傳送訊息時檢查資源(主題)是否授權(ACL)給改使用者alice

1.2 zookeeper與broker認證、鑑權

我們這一篇文章中zookeeper與broker認證,鑑權主要採取的方式為SASL/SCRAM + ACL,其核心設計圖如下所示:

Kafka ACL實現架構以及實操案例剖析

2、kafka SASL+ACL實戰

2.1 叢集配置

2.1.1 zookeeper SASL配置

在zookeeper的配置檔案中zoo.cfg中增加如下配置項:

sessionRequireClientSASLAuth=true
jaasLoginRenew=3600000
requireClientAuthScheme=sasl
zookeeper.sasl.client=true
authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider

並且新增JAAS配置檔案:zoo_jaas.conf,用於定義認證身份資訊,其配置內容如下所示:

Server {
       org.apache.zookeeper.server.auth.DigestLoginModule required
       username="zookeeper"
       password="zookeepersecret”
       user_kafka="
kafkasecret";
};

然後需要指定jaas配置檔案:

export SERVER_JVMFLAGS="-Djava.security.auth.login.config=/Users/vhicool/zookeeper/conf/zoo_jaas.conf"

透過如下命令啟動zookeeper服務端

./bin/zkServer.sh start-foreground

2.1.2 Kafka SASL配置

首先我們新增broker賬號,需要在broker重慶應用sasl+acl配置之前執行。

bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config 'SCRAM-SHA-256=[iterations=8192,password=adminsecret]' --entity-type users --entity-name admin

然後再新增管理賬號,管理員賬號用於運維人員維護叢集時使用,其具體命令如下:

bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config 'SCRAM-SHA-256=[iterations=8192,password=adminsecret]' --entity-type users --entity-name kafkaadmin

然後再服務端建立jaas.conf,具體的內容如下所示:

//broker與broker
KafkaServer {
    org.apache.kafka.common.security.plain.PlainLoginModule required
    username="admin"
    password="adminsecret";
};
//broker與zookeeper
Client{
    org.apache.kafka.common.security.plain.PlainLoginModule required
    username="kafka"
    password="kafkasecret";
};

然後透過-D引數指定kafka環境變數,使得SASL生效:

-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf

最後在kafka的server.properties配置檔案中配置如下內容:

#SASL/SCRAM
listeners=SASL_PLAINTEXT://host.name:port
security.inter.broker.protocol=SASL_PLAINTEXT
sasl.mechanism.inter.broker.protocol=SCRAM-SHA-256
sasl.enabled.mechanisms=SCRAM-SHA-25
#ACL
authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer
super.users=User:admin

2.2 新增認證、授權規則

除了使用kafka自帶cli,同時也可以使用kafka透過的api去維護:KafkaClientAdmin,如果使用該類進行操作,需要新增kafka client JAAS認證檔案:kafka_client_jaas.conf,具體的內容如下所示:

//kafka client與zookeeper SASL
Client{
    org.apache.kafka.common.security.plain.PlainLoginModule required
    username="kafka"
    password="kafkasecret";
};
// kafka client與broker SASL
KafkaClient {
    org.apache.kafka.common.security.plain.PlainLoginModule required
    username="kafkaadmin"
    password="adminsecret";
};

然後需要透過環境變數設定登入驗證檔案,具體命令如下:

 export KAFKA_OPTS="-Djava.security.auth.login.config=/etc/kafka/kafka_client_jaas.conf"

接下來我們嘗試使用命令列新增主題。

使用如下命令建立一個主題:

 bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic topic-1

給使用者Alice saal設定登入資訊:

bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config 'SCRAM-SHA-256=[iterations=8192,password=alice-secret]' --entity-type users --entity-name alice

並對Alice使用者對主題topic-1設定傳送許可權,程式碼如下所示:

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

經過上面的操作, 我們可以用下面的命令嘗試對topic-1主題傳送訊息:

bin/kafka-console-producer.sh --broker-list localhost:9092 --topic topic-1 --producer-property security.protocol=SASL_PLAINTEXT --producer-property sasl.mechanism=SCRAM-SHA-256

2.3 客戶端配置

在使用者alice配置SASL認證,並且授權主題topic-1傳送許可權後,客戶端透過原生api傳送訊息,示例程式碼如下所示:

  Properties kafkaProperties = new Properties();
  kafkaProperties.put(org.apache.kafka.clients.producer.ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,
    "org.apache.kafka.common.serialization.StringSerializer");
  kafkaProperties.put(org.apache.kafka.clients.producer.ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
    "org.apache.kafka.common.serialization.ByteArraySerializer");
  kafkaProperties.put("bootstrap.servers""localhost:9092");
  //SASL配置
  kafkaProperties.put("sasl.jaas.config","org.apache.kafka.common.security.scram.ScramLoginModule required username=\"alice\" password=\"alice-secret\";");
  kafkaProperties.put("security.protocol","SASL_PLAINTEXT");
  kafkaProperties.put("sasl.mechanism","SCRAM-SHA-256");

  KafkaProducer<String, byte[]> producer = new KafkaProducer<>(kafkaProperties);
  ProducerRecord<String, byte[]> record = new ProducerRecord<String, byte[]>("topic-1"nullnull"test message"null);
  producer.send(record).get();

3、自定義SASL、ACL儲存形式

3.1 SASL儲存形式

SASL的儲存形式主義分為本地儲存,zookeeper儲存和外部認證伺服器儲存,一一介紹如下:

  • 本地檔案儲存 PLAIN模式,SASL/PLAIN是一種簡單的使用者名稱/密碼認證機制,通常與TLS一起用於加密以實現安全認證。他的SASL認證是儲存在本地JAAS檔案,因此如果需要實現動態身份認證,需要擴充SASL認證介面

  • zookeeper儲存

  • SASL/SCRAM 它解決了與執行使用者名稱/密碼認證的傳統機制(如PLAIN和DIGEST-MD5)的安全問題。RFC 5802中定義了該機制。Kafka支援SCRAM-SHA-256和SCRAM-SHA-512,它們可以與TLS一起使用以執行安全認證。使用者名稱用作配置ACL等的認證主體。Kafka中的預設SCRAM實現在Zookeeper中儲存SCRAM憑據,適用於Zookeepher位於專用網路上的Kafka安裝

  • 外部認證伺服器儲存 SASL/Kerberos

kafka預設SASL是透過靜態JAAS檔案配置的,從Kafka 2.0版開始,可以透過使用配置選項sasl.server.callback.handler.class和sasl.client.callback.handler.class配置自己的回撥處理程式來從外部源獲取使用者名稱和密碼,從而避免在磁碟上儲存明文密碼。

  • sasl.server.callback.handler.class 實現 AuthenticateCallbackHandler 介面的 SASL 伺服器回撥處理程式類的完全限定名稱。伺服器回撥處理程式必須以偵聽器字首和小寫的 SASL 機制名稱為字首。例如,listener.name.sasl_ssl.plain.sasl.server.callback.handler.class=com.example.CustomPlainCallbackHandler

  • sasl.client.callback.handler.class 實現 AuthenticateCallbackHandler 介面的 SASL 客戶端回撥處理程式類的完全限定名稱。

3.2 ACL儲存形式

kafka預設ACL儲存在zookeeper,其時序圖如下所示:

Kafka ACL實現架構以及實操案例剖析

我們可以透過客戶端配置authorizer.class.name,自定義實現儲存位置。

kafka預設是透過zookeeper儲存ACL規則,實現類為:kafka.security.auth.SimpleAclAuthorizer。如果我們要擴充套件ACL儲存,需要自定義認證類並實現kafka.security.auth.Authorizer介面,包括實現authorize、addAcls、removeAcls、getAcls等方法,並在broker配置檔案中指定自定義的authorizer即可。

authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024420/viewspace-2935961/,如需轉載,請註明出處,否則將追究法律責任。

相關文章