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 生产集群验证;示例密码请替换后使用。

相关推荐
梦帮科技7 小时前
vLLM / TensorRT-LLM 极限推理:PagedAttention 细粒度物理页表管理与连续批处理(Continuous Batching)实战
数据结构·人工智能·分布式·python·深度学习·算法·vllm
用户1494484813209 小时前
同为消息队列,RocketMQ 和 Kafka 的底层设计差在哪?
kafka
Frank_refuel12 小时前
分布式RPC框架实战(二):服务端模块划分与底层设计
分布式·网络协议·rpc
开开心心就好12 小时前
办公软件卸载不干净?专用工具一键清残留
java·前端·人工智能·智能手机·kafka·excel·memcache
mftang1 天前
EtherCAT协议:从“飞读飞写”机制到分布式时钟同步的实时以太网架构深度解析
分布式·架构·ethercat·分布式时钟·从站控制器
ShineWinsu1 天前
对于Redis:Hash类型的解析
c++·redis·分布式·缓存·面试·hash·哈希表
东方芷兰2 天前
Agent 技术摘要 03 —— 基座模型、推理模型、Flash、联邦学习、分布式机器学习
人工智能·分布式·机器学习
程序猿乐锅2 天前
【黑马点评 | 第十一篇】关注 Feed 流实现
java·数据库·redis·分布式·后端·缓存·maven
ly76892 天前
ISR 收缩与 HW 推进:副本同步的边界条件与 UnderReplicated 排障
数据库·kafka·c#·linq·isr·hw·副本同步
j7~2 天前
【C++标准项目】C++基于protobuf的发布订阅式消息队列(篇一):项目概述+环境搭建
分布式·消息队列·rabbitmq·gtest·protobuf·muduo·sqlites