写点什么

Kafka SASL 用户认证机制

作者:spacerrobot
  • 2022-11-24
    北京
  • 本文字数:4186 字

    阅读完需:约 14 分钟

Kafka 的用户认证机制涉及的技术概念比较多,像 SASL、SCRAM、JAAS 等,这些技术分别是解决什么问题的?之间的关系如何?在实际 Kafka 使用中该如何配置?本文将辨析这些技术概念的含义与层次关系,并通过一个示例来展示如何配置 Kafka 使用 SASL 安全层做用户认证。

概念理解

  1. 监听器(Listener): Kafka Broker 可以启动多个实例,每个实例又可以监听多个端口,一个监听器就是其中一个实例 IP + 端口的组合。

  2. 监听器名字(Listener Name):为监听器起的名字,便于描述监听器的作用。一个 Kafka Broker 可以启动多个监听器,有了名字,也就能够在需要引用监听器的地方,通过名字指明引用的具体是哪个监听器。

  3. SASL(Simple Authentication and Security Layer):网络协议中使用的认证层,关键词是 Authentication,用于服务访问的身份认证。SASL 只是提供了一种认证框架,具体实现上可以选择不同的机制(Mechanism)。

  4. SCRAM(Salted Challenge Response Authentication Mechanism):SASL 机制家族的一种,是一套包含服务器和客户端双向确认的用户认证体系,配合信道加密可以比较好的抵御中间人、拖库、伪造等攻击。

  5. 监听器安全协议(Listener Security Protocol):Kafka 支持的安全协议有如下四种

  6. PLAINTEXT

  7. SSL

  8. SASL_PLAINTEXT

  9. SASL_SSL

  10. 安全协议由两部分组成,前半部分(SASL)决定是否验证用户身份;后半部分(PLAINTEXT/SSL)决定是否对传输信道加密,类似 HTTP 和 HTTPS。前两种安全协议不带 SASL,所以通信不需要配置用户凭证信息;而如果使用后两种安全协议通信,则必须配置用户凭证信息。

  11. SASL 机制(SASL Mechanism):Kafka 支持的 SASL 机制有如下五种

  12. GSSAPI (Kerberos)

  13. PLAIN

  14. SCRAM-SHA-256

  15. SCRAM-SHA-512

  16. OAUTHBEARER

  17. SASL 机制是配合安全协议来使用的,如果监听器选择了 SASL_PLAINTEXT 或 SASL_SSL 安全协议,则需要进一步设置 SASL 机制。由于 PLAINTEXT 或 SSL 安全协议并不会用到 SASL 机制,所以无需设置。

  18. 五种 SASL 机制中 GSSAPI 适用于使用 Kerberos 的场景, OAUTHBEARER 适用于使用 OAuth 2 授权框架的场景,SCRAM-SHA-512 可以认为是 SCRAM-SHA-256 的加强版,二者都是使用 SCRAM 机制。SCRAM 机制比 PLAIN 机制的优势有两点:(1)提供更好的安全性(密码不会在信道上传输);(2)可以动态增加用户凭证信息,无需重启服务。

  19. JAAS(Java Authentication and Authorization Service):Java 认证和授权服务,使用可插拔方式将认证授权逻辑和应用程序分离,实现认证授权服务的模块通过 JAAS 配置文件来指定。Kafka 使用 JAAS 来实现 SASL 认证机制,实现模块为 org.apache.kafka.common.security.scram.ScramLoginModule,并且将 JAAS 配置融合到了 Broker 配置文件中。

示例架构

示例架构如下图所示:



  1. Broker 有三个监听器:CONTROLLER 用于与 ZK 通信;INTERNAL 用于 Broker 之间通信;CLIENT 用于与客户端(生产者和消费者)通信。

  2. CONTROLLER 和 INTERNAL 监听器的安全协议使用最简单的 PLAINTEXT。

  3. CLIENT 监听器的安全协议使用 SASL_PLAINTEXT,并且 SASL 机制选用 SCRAM-SHA-512。如何配置和使用 SASL_PLAINTEXT 安全协议与 SASL 机制是本文的重点。

配置说明

  1. 配置三个监听器:CONTROLLER、INTERNAL 与 CLIENT。

# Broker 1listeners=INTERNAL://:29092,CONTROLLER://:29093,CLIENT://:29094
# Broker 2listeners=INTERNAL://:39092,CONTROLLER://:39093,CLIENT://:39094
复制代码


  1. 指定三个监听器的安全协议。

listener.security.protocol.map=INTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT,CLIENT:SASL_PLAINTEXT
复制代码


  1. 指定与控制面(ZK)通信使用 CONTROLLER 监听器,Broker 之间通信使用 INTERNAL 监听器。

control.plane.listener.name=CONTROLLERinter.broker.listener.name=INTERNAL
复制代码


  1. 如何指定与客户端通信用 CLIENT 监听器呢?这个通过客户端连接 Kafka 集群时的 --bootstrap-server 参数来指定,在该参数中使用 CLIENT 监听器对应的端口即可。

# producer client$ bin/kafka-console-producer.sh --bootstrap-server localhost:29094,localhost:39094 ...
# consumer client$ bin/kafka-console-consumer.sh --bootstrap-server localhost:29094,localhost:39094 ...
复制代码


  1. 由于 CLIENT 监听器使用了 SASL_PLAINTEXT 安全协议,需要为它指定 SASL 机制,这里使用 SCRAM-SHA-512 机制,并指定相应的 JAAS 配置(配置项名称格式为:listener.name.{listenerName}.{saslMechanism}.sasl.jaas.config)。

sasl.enabled.mechanisms=SCRAM-SHA-512listener.name.client.scram-sha-512.sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required
复制代码


  1. 协议是双向的,在服务端(Broker 端)配置好后,还需要在客户端(producer/consumer 端)配置,并且需要完全匹配,客户端配置文件如下,在 JAAS 配置部分指定了客户端连接 Broker 用的用户凭证(username/password)。这个凭证需要提前在 Kafka 集群上创建。

security.protocol=SASL_PLAINTEXTsasl.mechanism=SCRAM-SHA-512sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="xxxx" password="xxxx";
复制代码

示例验证

  1. 下载 Kafka 安装包并进入工作目录

$ curl -O https://www.apache.org/dyn/closer.cgi\?path\=/kafka/3.3.1/kafka_2.13-3.3.1.tgz$ tar -xzf kafka_2.13-3.3.1.tgz$ cd kafka_2.13-3.3.1
复制代码


  1. 运行 ZK

$ bin/zookeeper-server-start.sh config/zookeeper.properties
复制代码


  1. 配置 config/server1.properties 文件(Broker 1 的配置文件)

...broker.id=0...listeners=INTERNAL://:29092,CONTROLLER://:29093,CLIENT://:29094listener.security.protocol.map=INTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT,CLIENT:SASL_PLAINTEXTcontrol.plane.listener.name=CONTROLLERinter.broker.listener.name=INTERNALsasl.enabled.mechanisms=SCRAM-SHA-512listener.name.client.scram-sha-512.sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required;...log.dirs=/tmp/kafka-logs-1...
复制代码


  1. 配置 config/server2.properties 文件(Broker 2 的配置文件)

...broker.id=1...listeners=INTERNAL://:39092,CONTROLLER://:39093,CLIENT://:39094listener.security.protocol.map=INTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT,CLIENT:SASL_PLAINTEXTcontrol.plane.listener.name=CONTROLLERinter.broker.listener.name=INTERNALsasl.enabled.mechanisms=SCRAM-SHA-512listener.name.client.scram-sha-512.sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required;...log.dirs=/tmp/kafka-logs-2...
复制代码


  1. 运行两个 Broker 实例(Broker 1 和 Broker 2)

$ bin/kafka-server-start.sh config/server1.properties
$ bin/kafka-server-start.sh config/server2.properties
复制代码


  1. 创建三个用户:admin,writer 和 reader(访问 CONTROLLER 监听器)

$ bin/kafka-configs.sh --bootstrap-server localhost:29093,localhost:39093 --alter --add-config 'SCRAM-SHA-512=[password=admin]' --entity-type users --entity-name admin
$ bin/kafka-configs.sh --bootstrap-server localhost:29093,localhost:39093 --alter --add-config 'SCRAM-SHA-512=[password=writer]' --entity-type users --entity-name writer
$ bin/kafka-configs.sh --bootstrap-server localhost:29093,localhost:39093 --alter --add-config 'SCRAM-SHA-512=[password=reader]' --entity-type users --entity-name reader
复制代码


  1. 查看创建的用户信息(访问 CONTROLLER 监听器)

$ bin/kafka-configs.sh --bootstrap-server localhost:29093,localhost:39093 --describe --entity-type usersSCRAM credential configs for user-principal 'admin' are SCRAM-SHA-512=iterations=4096SCRAM credential configs for user-principal 'reader' are SCRAM-SHA-512=iterations=4096SCRAM credential configs for user-principal 'writer' are SCRAM-SHA-512=iterations=4096
复制代码


  1. 配置 config/command.conf (Topic 命令配置文件)

security.protocol=SASL_PLAINTEXTsasl.mechanism=SCRAM-SHA-512sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="admin" password="admin";
复制代码


  1. 配置 config/producer.conf (生产者配置文件)

security.protocol=SASL_PLAINTEXTsasl.mechanism=SCRAM-SHA-512sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="writer" password="writer";
复制代码


  1. 配置 config/consumer.conf(消费者配置文件 )

security.protocol=SASL_PLAINTEXTsasl.mechanism=SCRAM-SHA-512sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="reader" password="reader";
复制代码


  1. 用 admin 用户创建一个 topic(访问 CLIENT 监听器)

$ bin/kafka-topics.sh --bootstrap-server localhost:29094,localhost:39094 --create --topic test --command-config config/command.conf 
复制代码


  1. 用 writer 用户运行 producer 发送消息(访问 CLIENT 监听器)

$ bin/kafka-console-producer.sh --bootstrap-server localhost:29094,localhost:39094 --topic test --producer.config config/producer.conf > hello> world> 
复制代码


  1. 用 reader 用户运行 consumer 消费消息(访问 CLIENT 监听器)

$ bin/kafka-console-consumer.sh --bootstrap-server localhost:29094,localhost:39094 --topic test --from-beginning --consumer.config config/consumer.confhelloworld
复制代码

总结

  1. Kafka 安全协议是针对监听器配置的,一个 Broker 可以启多个监听器,不同的监听器可以使用不同的安全协议。

  2. Kafka 使用 SASL 安全层是为了解决与 Broker 通信的安全认证问题。SASL 配置有三个层面:协议层(SASL_PLAINTEXT、SASL_SSL),机制层(PLAIN、SCRAM-SHA-512 等)和 JAAS 实现层。

  3. 协议层的 PLAINTEXT,与机制层的 PLAIN 名字上有点像,但属于不同层面的概念,前者的对象是传输信道,后者的对象是认证信息,不要混淆。

  4. 必须保证服务端(Broker)与客户端(Producer/Consumer)的 SASL 配置在协议层、机制层和 JAAS 实现层的完全一致,否则无法通信。


用户头像

spacerrobot

关注

还未添加个人签名 2018-11-20 加入

还未添加个人简介

评论

发布
暂无评论
Kafka SASL 用户认证机制_kafka_spacerrobot_InfoQ写作社区