You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于KRaft的Kafka配置SASL/SCRAM实现用户主题权限控制报错求助

解决方案:KRaft Kafka 配置 SASL/SCRAM + SSL + 细粒度ACL权限控制

一、先解决当前SCRAM认证失败错误

你的报错核心是controller与broker间SCRAM认证凭证不匹配,结合Bitnami Kafka特性,问题出在以下几点:

  1. 混用Bitnami专属环境变量与原生Kafka JAAS配置
  2. Controller listener的认证机制与JAAS配置冲突
  3. 用户凭证未通过Bitnami专属变量生成正确的SCRAM哈希

修复步骤:

  1. 移除手动JAAS配置:Bitnami Kafka会自动生成JAAS配置,自定义的KAFKA_LISTENER_NAME_*_SASL_JAAS_CONFIG会覆盖自动生成内容,导致凭证不匹配,直接删除这些变量。
  2. 统一Controller与Broker认证机制:将controller的SASL机制改为SCRAM-SHA-256,和inter-broker保持一致,避免PLAIN与SCRAM混合冲突。
  3. 替换用户凭证变量:用Bitnami专属的KAFKA_SCRAM_USERS和KAFKA_SCRAM_PASSWORDS替代KAFKA_CLIENT_USERS/PASSWORDS,这两个变量会自动生成SCRAM所需的哈希凭证。

修改后的关键环境变量片段:

# Authentification
- KAFKA_CFG_SASL_ENABLED_MECHANISMS=SCRAM-SHA-256
- KAFKA_CFG_SASL_MECHANISM_CONTROLLER_PROTOCOL=SCRAM-SHA-256
- KAFKA_CFG_SASL_MECHANISM_INTER_BROKER_PROTOCOL=SCRAM-SHA-256
# 移除所有KAFKA_LISTENER_NAME_*_SASL_JAAS_CONFIG变量
- KAFKA_SCRAM_USERS=admin,user1,user2
- KAFKA_SCRAM_PASSWORDS=admin-secret,user1-secret,user2-secret

二、完整配置:SASL/SCRAM + SSL + ACL权限控制

要实现用户仅访问专属主题,需在SASL认证基础上结合Kafka ACL实现细粒度权限控制,同时配置SSL加密外部连接。

1. 三节点KRaft Docker Compose完整配置

version: '3.8'

services:
  kafka-0:
    image: docker.io/bitnami/kafka:${KAFKA_VERSION}
    hostname: kafka-0
    container_name: kafka-0
    ports:
      - "9094:9094"
    volumes:
      - ./kafka-ssl:/opt/bitnami/kafka/ssl
      - kafka-0-data:/bitnami/kafka
    environment:
      # KRaft基础配置
      - KAFKA_CFG_NODE_ID=0
      - KAFKA_CFG_PROCESS_ROLES=controller,broker
      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka-0:9093,1@kafka-1:9093,2@kafka-2:9093
      - KAFKA_KRAFT_CLUSTER_ID=abcdefghijklmnopqrstuv
      # 监听器配置
      - KAFKA_CFG_MESSAGE_MAX_BYTES=20000000
      - KAFKA_CFG_LISTENERS=BROKER://:9092,CONTROLLER://:9093,EXTERNAL://:9094
      - KAFKA_CFG_ADVERTISED_LISTENERS=BROKER://kafka-0:9092,EXTERNAL://${HOST_IP}:9094
      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=BROKER:SASL_PLAINTEXT,CONTROLLER:SASL_PLAINTEXT,EXTERNAL:SASL_SSL
      - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=BROKER
      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
      # 集群副本配置
      - KAFKA_CFG_OFFSETS_TOPIC_REPLICATION_FACTOR=3
      - KAFKA_CFG_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=3
      - KAFKA_CFG_TRANSACTION_STATE_LOG_MIN_ISR=2
      # SASL/SCRAM配置
      - KAFKA_CFG_SASL_ENABLED_MECHANISMS=SCRAM-SHA-256
      - KAFKA_CFG_SASL_MECHANISM_CONTROLLER_PROTOCOL=SCRAM-SHA-256
      - KAFKA_CFG_SASL_MECHANISM_INTER_BROKER_PROTOCOL=SCRAM-SHA-256
      - KAFKA_SCRAM_USERS=admin,user1,user2
      - KAFKA_SCRAM_PASSWORDS=admin-secret,user1-secret,user2-secret
      # SSL配置
      - KAFKA_CFG_SSL_KEYSTORE_LOCATION=/opt/bitnami/kafka/ssl/kafka.keystore.jks
      - KAFKA_CFG_SSL_KEYSTORE_PASSWORD=keystore-secret
      - KAFKA_CFG_SSL_KEY_PASSWORD=key-secret
      - KAFKA_CFG_SSL_TRUSTSTORE_LOCATION=/opt/bitnami/kafka/ssl/kafka.truststore.jks
      - KAFKA_CFG_SSL_TRUSTSTORE_PASSWORD=truststore-secret
      # ACL权限控制
      - KAFKA_CFG_AUTHORIZER_CLASS_NAME=org.apache.kafka.metadata.authorizer.StandardAuthorizer
      - KAFKA_CFG_ALLOW_EVERYONE_IF_NO_ACL_FOUND=false
      - KAFKA_CFG_SUPER_USERS=User:admin

  kafka-1:
    image: docker.io/bitnami/kafka:${KAFKA_VERSION}
    hostname: kafka-1
    container_name: kafka-1
    volumes:
      - ./kafka-ssl:/opt/bitnami/kafka/ssl
      - kafka-1-data:/bitnami/kafka
    environment:
      - KAFKA_CFG_NODE_ID=1
      - KAFKA_CFG_PROCESS_ROLES=controller,broker
      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka-0:9093,1@kafka-1:9093,2@kafka-2:9093
      - KAFKA_KRAFT_CLUSTER_ID=abcdefghijklmnopqrstuv
      - KAFKA_CFG_LISTENERS=BROKER://:9092,CONTROLLER://:9093,EXTERNAL://:9094
      - KAFKA_CFG_ADVERTISED_LISTENERS=BROKER://kafka-1:9092,EXTERNAL://${HOST_IP}:9095
      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=BROKER:SASL_PLAINTEXT,CONTROLLER:SASL_PLAINTEXT,EXTERNAL:SASL_SSL
      - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=BROKER
      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
      - KAFKA_CFG_OFFSETS_TOPIC_REPLICATION_FACTOR=3
      - KAFKA_CFG_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=3
      - KAFKA_CFG_TRANSACTION_STATE_LOG_MIN_ISR=2
      - KAFKA_CFG_SASL_ENABLED_MECHANISMS=SCRAM-SHA-256
      - KAFKA_CFG_SASL_MECHANISM_CONTROLLER_PROTOCOL=SCRAM-SHA-256
      - KAFKA_CFG_SASL_MECHANISM_INTER_BROKER_PROTOCOL=SCRAM-SHA-256
      - KAFKA_SCRAM_USERS=admin,user1,user2
      - KAFKA_SCRAM_PASSWORDS=admin-secret,user1-secret,user2-secret
      - KAFKA_CFG_SSL_KEYSTORE_LOCATION=/opt/bitnami/kafka/ssl/kafka.keystore.jks
      - KAFKA_CFG_SSL_KEYSTORE_PASSWORD=keystore-secret
      - KAFKA_CFG_SSL_KEY_PASSWORD=key-secret
      - KAFKA_CFG_SSL_TRUSTSTORE_LOCATION=/opt/bitnami/kafka/ssl/kafka.truststore.jks
      - KAFKA_CFG_SSL_TRUSTSTORE_PASSWORD=truststore-secret
      - KAFKA_CFG_AUTHORIZER_CLASS_NAME=org.apache.kafka.metadata.authorizer.StandardAuthorizer
      - KAFKA_CFG_ALLOW_EVERYONE_IF_NO_ACL_FOUND=false
      - KAFKA_CFG_SUPER_USERS=User:admin

  kafka-2:
    image: docker.io/bitnami/kafka:${KAFKA_VERSION}
    hostname: kafka-2
    container_name: kafka-2
    volumes:
      - ./kafka-ssl:/opt/bitnami/kafka/ssl
      - kafka-2-data:/bitnami/kafka
    environment:
      - KAFKA_CFG_NODE_ID=2
      - KAFKA_CFG_PROCESS_ROLES=controller,broker
      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka-0:9093,1@kafka-1:9093,2@kafka-2:9093
      - KAFKA_KRAFT_CLUSTER_ID=abcdefghijklmnopqrstuv
      - KAFKA_CFG_LISTENERS=BROKER://:9092,CONTROLLER://:9093,EXTERNAL://:9094
      - KAFKA_CFG_ADVERTISED_LISTENERS=BROKER://kafka-2:9092,EXTERNAL://${HOST_IP}:9096
      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=BROKER:SASL_PLAINTEXT,CONTROLLER:SASL_PLAINTEXT,EXTERNAL:SASL_SSL
      - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=BROKER
      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
      - KAFKA_CFG_OFFSETS_TOPIC_REPLICATION_FACTOR=3
      - KAFKA_CFG_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=3
      - KAFKA_CFG_TRANSACTION_STATE_LOG_MIN_ISR=2
      - KAFKA_CFG_SASL_ENABLED_MECHANISMS=SCRAM-SHA-256
      - KAFKA_CFG_SASL_MECHANISM_CONTROLLER_PROTOCOL=SCRAM-SHA-256
      - KAFKA_CFG_SASL_MECHANISM_INTER_BROKER_PROTOCOL=SCRAM-SHA-256
      - KAFKA_SCRAM_USERS=admin,user1,user2
      - KAFKA_SCRAM_PASSWORDS=admin-secret,user1-secret,user2-secret
      - KAFKA_CFG_SSL_KEYSTORE_LOCATION=/opt/bitnami/kafka/ssl/kafka.keystore.jks
      - KAFKA_CFG_SSL_KEYSTORE_PASSWORD=keystore-secret
      - KAFKA_CFG_SSL_KEY_PASSWORD=key-secret
      - KAFKA_CFG_SSL_TRUSTSTORE_LOCATION=/opt/bitnami/kafka/ssl/kafka.truststore.jks
      - KAFKA_CFG_SSL_TRUSTSTORE_PASSWORD=truststore-secret
      - KAFKA_CFG_AUTHORIZER_CLASS_NAME=org.apache.kafka.metadata.authorizer.StandardAuthorizer
      - KAFKA_CFG_ALLOW_EVERYONE_IF_NO_ACL_FOUND=false
      - KAFKA_CFG_SUPER_USERS=User:admin

volumes:
  kafka-0-data:
  kafka-1-data:
  kafka-2-data:

2. SSL证书生成(本地自签示例)

在./kafka-ssl目录下执行以下命令生成JKS证书:

# 生成keystore
keytool -genkey -alias kafka -keyalg RSA -keystore kafka.keystore.jks -storepass keystore-secret -keypass key-secret -validity 3650 -dname "CN=kafka,OU=dev,O=company,L=city,S=state,C=CN"

# 导出证书并生成truststore
keytool -export -alias kafka -file kafka.crt -keystore kafka.keystore.jks -storepass keystore-secret
keytool -import -alias kafka -file kafka.crt -keystore kafka.truststore.jks -storepass truststore-secret -noprompt

三、动态添加SCRAM用户与ACL权限配置

1. 动态添加SCRAM用户

进入任意Kafka容器,使用kafka-configs.sh添加用户:

docker exec -it kafka-0 bash

# 先创建admin的客户端配置文件
cat > /opt/bitnami/kafka/config/admin-client.properties << EOF
security.protocol=SASL_PLAINTEXT
sasl.mechanism=SCRAM-SHA-256
sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="admin" password="admin-secret";
EOF

# 添加新用户user3
kafka-configs.sh --bootstrap-server kafka-0:9092 --command-config /opt/bitnami/kafka/config/admin-client.properties --alter --add-config 'SCRAM-SHA-256=[password=user3-secret]' --entity-type users --entity-name user3

2. 配置ACL权限(用户仅访问专属主题)

以user1仅能访问user1-topic为例:

# 授予user1对user1-topic的读写权限
kafka-acls.sh --bootstrap-server kafka-0:9092 --command-config /opt/bitnami/kafka/config/admin-client.properties --add --allow-principal User:user1 --operation Read --operation Write --topic user1-topic

# 授予user1对自身消费组的权限
kafka-acls.sh --bootstrap-server kafka-0:9092 --command-config /opt/bitnami/kafka/config/admin-client.properties --add --allow-principal User:user1 --operation Read --operation Write --group user1-group

四、Python客户端配置示例(confluent-kafka)

from confluent_kafka import Producer, Consumer

# 生产者配置
producer_conf = {
    'bootstrap.servers': 'your-host-ip:9094',
    'security.protocol': 'SASL_SSL',
    'sasl.mechanism': 'SCRAM-SHA-256',
    'sasl.username': 'user1',
    'sasl.password': 'user1-secret',
    'ssl.ca.location': './kafka-ssl/kafka.crt',
    'client.id': 'user1-producer'
}

# 消费者配置
consumer_conf = {
    'bootstrap.servers': 'your-host-ip:9094',
    'security.protocol': 'SASL_SSL',
    'sasl.mechanism': 'SCRAM-SHA-256',
    'sasl.username': 'user1',
    'sasl.password': 'user1-secret',
    'ssl.ca.location': './kafka-ssl/kafka.crt',
    'group.id': 'user1-group',
    'auto.offset.reset': 'earliest'
}

内容的提问来源于stack exchange,提问作者Vladimir Shebuniayeu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 04:19:52