Kafka 集群开启 SASL 认证实战(二):外置 ZooKeeper 之 kafka 与 zk 间认证

Kafka 集群开启 SASL 认证实战(二):外置 ZooKeeper 之 kafka 与 zk 间认证

很多场景下 Kafka broker 对内网客户端可以不加认证,但 kafka 与 ZooKeeper 之间的通道必须锁 ------zk 里存着 broker 元数据和消费者位移,谁都能连上去 rmr / 一键清空。本篇讲外置 ZooKeeper 场景下只做 kafka↔zk 间 SASL 认证的最小配置,不动 broker 对客户端的协议,业务应用零改造。配置在 ZooKeeper 3.6.3 + Kafka 2.5.1 生产集群验证通过。

系列导航

场景 链接
内置 ZooKeeper 的 Kafka 集群加 SASL 全套配置 已发布,点击直达
外置 ZooKeeper,只做 kafka↔zk 之间认证(本篇) 本篇
外置 ZooKeeper 完整版:quorum 认证 + zk ACL + 客户端认证 敬请期待

一、适用场景与版本要求

适用判断:客户端都在可信内网、等保只要求"关键链路认证"时,用本篇最小方案;如果 kafka 也要对客户端加密码,直接看第三篇。

硬性限制 :ZooKeeper 3.6.0 及以上 ------sessionRequireClientSASLAuth 等参数 3.6 才有。本文以 3.6.3 为例。

最终效果:zk 的 quorum(集群节点间)通信和 server-client 通信都要求 SASL,kafka 用账号连 zk,其他未认证客户端一律拒绝。

二、停服务

登录每台服务器,先杀 Kafka 再杀 ZooKeeper:

bash 复制代码
[root@kafka01 ~]# jps
29552 Jps
11923 QuorumPeerMain
13053 Kafka
[root@kafka01 ~]# kill -9 11923 13053

三、ZooKeeper 侧配置

进入 zk 配置目录(本文密码用 Test@12345 演示,上线前替换):

bash 复制代码
cd /opt/module/apache-zookeeper-3.6.3-bin/conf

3.1 zk_server.jaas(服务端身份 + 客户端账号库)

text 复制代码
Server {
    org.apache.zookeeper.server.auth.DigestLoginModule required
    user_super="Test@12345"
    user_zkclient="Test@12345";
};

QuorumServer {
    org.apache.zookeeper.server.auth.DigestLoginModule required
    user_quorum="Test@12345";
};

QuorumLearner {
    org.apache.zookeeper.server.auth.DigestLoginModule required
    username="quorum"
    password="Test@12345";
};

三个段的分工

用途
Server zk 对客户端提供服务时的认证,user_xxx 是账号库(kafka 用 zkclient 这个账号连入)
QuorumServer zk 集群选举/复制通道的服务端身份
QuorumLearner follower/observer 节点作为 learner 连 leader 时的客户端身份

3.2 zk_client.jaas(zk 自带命令行工具用)

text 复制代码
Client {
    org.apache.zookeeper.server.auth.DigestLoginModule required
    username="zkclient"
    password="Test@12345";
};

3.3 java.env(挂载 JAAS 的 JVM 参数)

bash 复制代码
vi java.env
bash 复制代码
SERVER_JVMFLAGS="-Djava.security.auth.login.config=/opt/module/apache-zookeeper-3.6.3-bin/conf/zk_server.jaas"
CLIENT_JVMFLAGS="${CLIENT_JVMFLAGS} -Djava.security.auth.login.config=/opt/module/apache-zookeeper-3.6.3-bin/conf/zk_client.jaas"

3.4 zoo.cfg 追加认证参数

properties 复制代码
# ===== Server-Server (quorum) 互相认证 =====
quorum.auth.enableSasl=true
quorum.auth.learnerRequireSasl=true
quorum.auth.serverRequireSasl=true
quorum.auth.learner.saslLoginContext=QuorumLearner
quorum.auth.server.saslLoginContext=QuorumServer
# 建议设为集群节点数 n*2
quorum.cnxn.threads.size=6

# ===== Server-Client 之间认证 =====
authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
# 强制客户端必须 SASL 认证(zk >= 3.6.0)
sessionRequireClientSASLAuth=true

sessionRequireClientSASLAuth=true 是"锁死"的关键------不开的话,不带认证的客户端照样能连。zk 集群里 observer 节点没有投票权,但不影响本配置。

把 4 个文件拷贝到 zk 集群所有节点

四、Kafka 侧配置

4.1 kafka.jaas(只需要 Client 段)

bash 复制代码
cd /opt/module/kafka_2.12-2.5.1/config
vi kafka.jaas
text 复制代码
Client {
    org.apache.kafka.common.security.plain.PlainLoginModule required
    username="zkclient"
    password="Test@12345";
};

注意 LoginModule 用的是 kafka 包里的 PlainLoginModule (不是 zk 的 DigestLoginModule)------kafka 连 zk 走 PLAIN 机制即可,账号对应 zk_server.jaas 里的 user_zkclient

4.2 server.properties

追加一行:

properties 复制代码
zookeeper.client.sasl=true

同样检查并注释掉残留的旧配置:

properties 复制代码
#advertised.host.name=192.168.10.31
#advertised.port=9092

4.3 启动脚本挂 JAAS

修改 kafka/bin/kafka-run-class.sh(一处生效,所有 kafka 命令行工具都会带上):

bash 复制代码
vi /opt/module/kafka_2.12-2.5.1/bin/kafka-run-class.sh

在脚本靠前位置添加:

bash 复制代码
export KAFKA_OPTS="-Djava.security.auth.login.config=/opt/module/kafka_2.12-2.5.1/config/kafka.jaas"

kafka.jaas 拷贝到所有 broker 节点,server.properties 按各节点 IP 调整后分发。

五、启动与验证

先 zk 后 kafka

bash 复制代码
cd /opt/module/apache-zookeeper-3.6.3-bin
./bin/zkServer.sh start

cd /opt/module/kafka_2.12-2.5.1
./bin/kafka-server-start.sh -daemon ./config/server.properties

验证三连:

bash 复制代码
# 1. broker 正常注册(说明 kafka->zk 认证通了)
./bin/kafka-topics.sh --bootstrap-server 192.168.10.31:9092 --list

# 2. 裸连 zk 被拒(不带 JAAS 的 zkCli 直接连会被 sessionRequireClientSASLAuth 挡掉)
./bin/zkCli.sh -server 192.168.10.31:2181

# 3. 命令行生产消费不受影响(本方案不动客户端协议)
./bin/kafka-console-producer.sh --broker-list 192.168.10.31:9092 \
  --producer.config ./config/producer.properties --topic test-topic

六、踩坑清单

现象 解法
zk 版本低于 3.6.0 sessionRequireClientSASLAuth 不生效或不识别 先升级 zk
忘注释 advertised.host.name broker 起来了客户端连不上 注释掉旧配置
java.env 路径写错 zk 起不来,日志报找不到 LoginModule 核对绝对路径
只改了部分 zk 节点 集群选举分裂、脑裂 所有 zk 节点同步改
kafka.jaas 用了 zk 的 DigestLoginModule broker 连 zk 认证失败 用 kafka 的 PlainLoginModule

总结

外置 zk 只锁 kafka↔zk 通道的方案,改动集中在 zk 侧 4 个文件(jaas×2 + java.env + zoo.cfg)+ kafka 侧 2 处(kafka.jaas + zookeeper.client.sasl),客户端协议完全不动,业务零感知。下一篇是本系列终章:在外置 zk 场景上叠加 kafka 客户端认证和 zk ACL 白名单,做到"内外都锁死",敬请期待。

你们 zk 集群现在有没有裸奔?有没有被误操作删过节点的经历?评论区聊聊。


系列文章配置在 ZooKeeper 3.6.3 + Kafka 2.5.1 生产集群验证;示例密码请替换后使用。

相关推荐
KANGBboy9 小时前
doris+kafka安装部署(单机+集群)二时钟服务器 java_home
服务器·分布式
爱笑的k1111 小时前
分布式通信原语
分布式·ai infra
实战派K8S&DB11 小时前
GaussDB 高可用演进:从流复制到 DCF 分布式共识
分布式·gaussdb
写后端的胖头鱼12 小时前
【高频面试题】分布式锁在项目中的应用
java·分布式·后端·分布式锁·高频面试题
clz131452113 小时前
Kafka 日消 10 亿场景:用 ConcurrentLinkedQueue 实现高性能批量消费缓冲
分布式·kafka·linq
隐擎fox1 天前
高性能网络爬虫架构设计:基于 Python 的长连接复用与分布式会话池调度实践
分布式·python·网络协议·tcp/ip·高并发·网络爬虫、
闲云自留地1 天前
云平台存储管理员:Cinder 创建挂载卷 + Swift 分布式存储原理
分布式·wpf·swift
橙子圆1231 天前
RabbitMQ知识1
分布式·rabbitmq
(Charon)1 天前
【Kafka】消息队列学习(一):为什么需要Kafka?从消息队列到整体架构
学习·架构·kafka