Kafka如何授权,看一篇就知道!

199 阅读8分钟

Kafka在KRaft模式下实现ACL授权策略

docker-compose.yml

version: "3.3"
services:
  kafka:
    image: 'bitnami/kafka:3.7.0-debian-12-r3'
    ports:
      - '9092:9092'
    environment:
      - KAFKA_CFG_NODE_ID=0
      - KAFKA_CFG_PROCESS_ROLES=controller,broker
      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9093
      - KAFKA_CFG_LISTENERS=SASL_PLAINTEXT://:9092,CONTROLLER://:9093
      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT
      - KAFKA_CFG_ADVERTISED_LISTENERS=SASL_PLAINTEXT://xxx:xxx:xxx:xxx:9092
      
      - KAFKA_CLIENT_USERS=kafkaMaster;kafka1
      - KAFKA_CLIENT_PASSWORDS=kafkaMaster@123;123456
      
      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
      - KAFKA_CFG_SASL_MECHANISM_CONTROLLER_PROTOCOL=PLAIN
      - KAFKA_CONTROLLER_USER=kafkaMaster
      - KAFKA_CONTROLLER_PASSWORD=kafkaMaster@123
      
      - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=SASL_PLAINTEXT
      - KAFKA_CFG_SASL_MECHANISM_INTER_BROKER_PROTOCOL=PLAIN
      - KAFKA_INTER_BROKER_USER=kafkaMaster
      - KAFKA_INTER_BROKER_PASSWORD=kafkaMaster@123

      - KAFKA_CFG_ALLOW_EVERYONE_IF_NO_ACL_FOUND=false
      - KAFKA_CFG_SUPER_USERS=User:kafkaMaster;User:ANONYMOUS
      - KAFKA_CFG_AUTHORIZER_CLASS_NAME=org.apache.kafka.metadata.authorizer.StandardAuthorizer

    volumes:
      - ./client.properties:/tmp/client.properties  # 认证配置
      - ./client.properties:/opt/bitnami/kafka/config/sasl_config.properties  # 认证配置
      - ./kafka:/bitnami/kafka
#      - ./config:/opt/bitnami/kafka/config

# 注释版本
version: "3.3"  # 指定 docker-compose 文件的版本
services:
  kafka:
    image: 'bitnami/kafka:3.7.0-debian-12-r3'  # 使用的 Kafka 镜像
    ports:
      - '9092:9092'  # 端口映射,将宿主机的 9092 端口映射到容器的 9092 端口
    environment:
      - KAFKA_CFG_NODE_ID=0  # Kafka 节点 ID,在 KRaft 模式下,每个节点都需要一个唯一的 ID
      - KAFKA_CFG_PROCESS_ROLES=controller,broker  # 节点角色,这里配置为同时担任 controller 和 broker
      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9093  # 控制器法定投票节点,格式为 id@host:port,这里配置了自身作为唯一的 controller
      - KAFKA_CFG_LISTENERS=SASL_PLAINTEXT://:9092,CONTROLLER://:9093  # Kafka 监听器,配置了两个监听器:SASL_PLAINTEXT 用于客户端连接,CONTROLLER 用于控制器之间的通信
      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT  # 监听器安全协议映射,将 CONTROLLER 监听器映射到 PLAINTEXT 协议,SASL_PLAINTEXT 监听器映射到 SASL_PLAINTEXT 协议
      - KAFKA_CFG_ADVERTISED_LISTENERS=SASL_PLAINTEXT://xxx:xxx:xxx:xxx:9092  # Kafka 广播监听器,客户端将通过这个地址和端口连接到 Kafka。需要配置为客户端可以访问的地址和端口。

      - KAFKA_CLIENT_USERS=kafkaMaster;kafka1  # 允许连接到 Kafka 的客户端用户列表,用分号分隔
      - KAFKA_CLIENT_PASSWORDS=kafkaMaster@123;123456  # 客户端用户对应的密码,用分号分隔,顺序与 KAFKA_CLIENT_USERS 对应

      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER  # 控制器监听器的名称
      - KAFKA_CFG_SASL_MECHANISM_CONTROLLER_PROTOCOL=PLAIN  # 控制器监听器的 SASL 机制,这里设置为 PLAIN
      - KAFKA_CONTROLLER_USER=kafkaMaster  # 用于控制器间认证的用户名
      - KAFKA_CONTROLLER_PASSWORD=kafkaMaster@123  # 用于控制器间认证的密码

      - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=SASL_PLAINTEXT  # broker 间通信的监听器名称
      - KAFKA_CFG_SASL_MECHANISM_INTER_BROKER_PROTOCOL=PLAIN  # broker 间通信的 SASL 机制,这里设置为 PLAIN
      - KAFKA_INTER_BROKER_USER=kafkaMaster  # 用于 broker 间认证的用户名
      - KAFKA_INTER_BROKER_PASSWORD=kafkaMaster@123  # 用于 broker 间认证的密码

      - KAFKA_CFG_ALLOW_EVERYONE_IF_NO_ACL_FOUND=false  # 如果没有找到 ACL,是否允许所有人访问,这里设置为 false,表示禁止访问
      - KAFKA_CFG_SUPER_USERS=User:kafkaMaster;User:ANONYMOUS  # 超级用户列表,用分号分隔,这里的 ANONYMOUS 用户比较特殊,一般不建议添加
      - KAFKA_CFG_AUTHORIZER_CLASS_NAME=org.apache.kafka.metadata.authorizer.StandardAuthorizer  # 授权器类名,这里使用了 Kafka 3.5 引入的新的标准授权器

    volumes:
      - ./client.properties:/tmp/client.properties  # 将宿主机当前目录下的 client.properties 文件挂载到容器的 /tmp/client.properties,用于 kafka-acls.sh 等客户端工具的认证配置
      - ./client.properties:/opt/bitnami/kafka/config/sasl_config.properties  # 将宿主机当前目录下的 client.properties 文件挂载到容器的 /opt/bitnami/kafka/config/sasl_config.properties,用于配置 SASL 认证
      - ./data:/bitnami/kafka/data  # 将宿主机当前目录下的 data 目录挂载到容器的 /bitnami/kafka/data,用于持久化 Kafka 的数据
#      - ./config:/opt/bitnami/kafka/config # 注释掉了将宿主机的 config 目录挂载到容器的配置目录

client.properties

security.protocol=SASL_PLAINTEXT
sasl.mechanism=PLAIN
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="kafkaMaster" password="kafkaMaster@123";

常用命令

查询/生产/消费topic

# 查询topic
kafka-topics.sh --list --bootstrap-server localhost:9092 --command-config /tmp/client.properties

# 创建topic
kafka-topics.sh --create --topic test_kafka --bootstrap-server localhost:9092 --partitions 3 --replication-factor 1 --command-config /tmp/client.properties

# 生产
kafka-console-producer.sh --bootstrap-server localhost:9092 --topic test_topic --producer.config /opt/bitnami/kafka/config/producer.properties

# 消费
kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test_kafka --consumer.config /opt/bitnami/kafka/config/consumer.properties

# 消费数据
kafka-console-consumer.sh \
  --bootstrap-server localhost:9092 \
  --topic test_kafka \
  --from-beginning \
  --formatter kafka.tools.DefaultMessageFormatter \
  --consumer.config /tmp/client.properties \
  --property print.key=true \
  --property key.separator=":"
  --property print.timestamp=true

#生产数据,例如1:1
kafka-console-producer.sh \
  --bootstrap-server localhost:9092 \
  --topic test_kafka \
  --property parse.key=true \
  --property key.separator=":" \
  --producer.config /opt/bitnami/kafka/config/producer.properties
  --property key.serializer=org.apache.kafka.common.serialization.StringSerializer \
  --property value.serializer=org.apache.kafka.common.serialization.StringSerializer

查看 ACL 列表

# 查看所有 ACL
kafka-acls.sh --bootstrap-server 127.0.0.1:9092 --command-config /tmp/client.properties --list

# 查看特定主题的 ACL
kafka-acls.sh --bootstrap-server 127.0.0.1:9092 --command-config /tmp/client.properties --list --topic test_kafka

# 查看特定用户的所有 ACL
kafka-acls.sh --bootstrap-server 127.0.0.1:9092 --command-config /tmp/client.properties --list --principal User:kafka1

# 查看特定消费者组的 ACL
kafka-acls.sh --bootstrap-server 127.0.0.1:9092 --command-config /tmp/client.properties --list --group my-group

授权 (添加 ACL):

  • 授予用户 kafka1 对主题 test_kafka 的所有权限:

    kafka-acls.sh --bootstrap-server 127.0.0.1:9092 --command-config /tmp/client.properties --add --allow-principal User:kafka1 --operation all --topic test_kafka
    
  • 授予用户 kafka1 对主题 test_kafka 的读取权限:

    kafka-acls.sh --bootstrap-server 127.0.0.1:9092 --command-config /tmp/client.properties --add --allow-principal User:kafka1 --operation Read --topic tests_kafka
    
  • 授予用户 kafka1 对主题 test_kafka 的写入权限:

    kafka-acls.sh --bootstrap-server 127.0.0.1:9092 --command-config /tmp/client.properties --add --allow-principal User:kafka1 --operation Write --topic test_kafka
    
  • 授予用户 kafka1 对主题 test_kafka 的生产 (Produce) 权限 (等同于 Create, Describe, Write):

    kafka-acls.sh --bootstrap-server 127.0.0.1:9092 --command-config /tmp/client.properties --add --allow-principal User:kafka1 --producer --topic test_kafka
    
  • 授予用户 kafka1 对消费者组 my-group 的消费 (Consume) 权限 (等同于 Read, Describe):

    kafka-acls.sh --bootstrap-server 127.0.0.1:9092 --command-config /tmp/client.properties --add --allow-principal User:kafka1 --consumer --group my-group --topic test_kafka
    
  • 授予用户 kafka1 对集群的创建主题权限:

    kafka-acls.sh --bootstrap-server 127.0.0.1:9092 --command-config /tmp/client.properties --add --allow-principal User:kafka1 --operation Create --cluster
    

3. 取消授权 (删除 ACL):

  • 取消用户 kafka1 对主题 test_kafka 的所有权限:

    kafka-acls.sh --bootstrap-server 127.0.0.1:9092 --command-config /tmp/client.properties --remove --allow-principal User:kafka1 --operation all --topic test_kafka
    
  • 取消用户 kafka1 对主题 test_kafka 的读取权限:

    kafka-acls.sh --bootstrap-server 127.0.0.1:9092 --command-config /tmp/client.properties --remove --allow-principal User:kafka1 --operation Read --topic test_kafka
    
  • 取消用户 kafka1 对主题 test_kafka 的写入权限:

    kafka-acls.sh --bootstrap-server 127.0.0.1:9092 --command-config /tmp/client.properties --remove --allow-principal User:kafka1 --operation Write --topic test_kafka
    

其他常用选项:

  • -deny-principal User:<用户名>: 拒绝某个用户的权限 (不常用,建议使用 -remove 取消授权)。
  • -allow-host <主机名>: 允许来自特定主机的访问 (通常不需要指定,默认允许所有主机 ``)。
  • -resource-pattern-type <模式类型>: 指定资源名称的模式类型,可以是 LITERAL (精确匹配) 或 PREFIXED (前缀匹配)。例如,-resource-pattern-type PREFIXED --topic "test_" 可以匹配所有以 test_ 开头的主题。

附录

ACL 可以应用于以下几种资源类型:

  • Topic: 主题
  • Group: 消费者组
  • Cluster: Kafka 集群
  • TransactionalId: 事务 ID
  • DelegationToken: 委托令牌 (用于安全委派)

权限 (Operations):

针对不同的资源类型,可以授予或拒绝以下权限:

权限 (Operation)描述适用资源类型
All所有权限所有资源类型
Read读取权限TopicGroupTransactionalIdDelegationToken
Write写入权限TopicTransactionalId
Create创建权限TopicGroupCluster (创建主题), TransactionalId (生成新的事务 ID)
Delete删除权限TopicGroup
Alter修改权限TopicGroup
Describe查看描述信息的权限TopicGroupClusterTransactionalIdDelegationToken
ClusterAction集群操作权限,例如创建或删除代理,修改集群配置等Cluster
DescribeConfigs查看配置信息的权限TopicGroupCluster
AlterConfigs修改配置信息的权限TopicGroupCluster
IdempotentWrite幂等写入权限Cluster

权限说明:

  • Read:

    • Topic: 允许从主题消费消息。
    • Group: 允许读取消费者组的元数据 (例如偏移量)。
    • TransactionalId: 允许使用指定的事务 ID。
    • DelegationToken: 允许描述 (查看) 委托令牌。
  • Write:

    • Topic: 允许向主题生产消息。
    • TransactionalId: 允许使用指定的事务 ID 写入数据。
  • Create:

    • Topic: 允许创建主题。
    • Group: 允许创建消费者组。
    • Cluster: 允许创建主题 (需要 ClusterAction 权限才能创建或删除代理)。
    • TransactionalId: 允许生成新的事务 ID。
  • Delete:

    • Topic: 允许删除主题。
    • Group: 允许删除消费者组。
  • Alter:

    • Topic: 允许修改主题的配置 (例如分区数、副本数)。
    • Group: 允许修改消费者组的元数据 (例如重置偏移量)。
  • Describe:

    • Topic: 允许查看主题的描述信息 (例如分区、副本)。
    • Group: 允许查看消费者组的描述信息 (例如成员、偏移量)。
    • Cluster: 允许查看集群的描述信息 (例如代理列表)。
    • TransactionalId: 允许查看事务 ID 的描述信息。
    • DelegationToken: 允许查看委托令牌的描述信息。
  • ClusterAction: 允许执行集群级别的操作,例如添加、删除或重新配置代理。

  • DescribeConfigs: 允许查看指定资源的配置信息。

  • AlterConfigs: 允许修改指定资源的配置信息。

  • IdempotentWrite: 允许进行幂等写入操作,这对于启用 Kafka 的 Exactly-Once 语义 (EOS) 是必需的。

常用权限组合:

  • 生产者 (Producer): 通常需要 CreateDescribeWrite 权限。可以使用 -producer 简写。
  • 消费者 (Consumer): 通常需要 ReadDescribe 权限。可以使用 -consumer 简写。

-operation 选项后面跟的就是具体的权限 (Operations) 名称,例如 WriteReadCreateDeleteAlter 等。

kafka-acls.sh 命令使用 --operation 选项来指定你要添加或删除的 ACL 规则中的操作权限。

例如:

  • -operation Write 表示写入权限,允许用户向主题生产消息。
  • -operation Read 表示读取权限,允许用户从主题消费消息或读取消费者组的元数据。
  • -operation Create 表示创建权限,允许用户创建主题、消费者组或事务 ID。
  • -operation Delete 表示删除权限,允许用户删除主题或消费者组。
  • -operation All 表示所有权限,这是最高级别的权限,拥有该权限的用户可以执行任何操作。

借鉴:

juejin.cn/post/729455…

blog.csdn.net/u010533742/…

www.cnblogs.com/changxy-cod…

KafkaTool连接

image.png image.png image.png image.png

org.apache.kafka.common.security.plain.PlainLoginModule required username="kafkaMaster" password="kafkaMaster@123";