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

相关推荐
kiwixing9 小时前
GaussDB|集中式还是分布式?三把尺子选型
分布式·gaussdb
真上帝的左手19 小时前
30. 技术专题-‌应用框架组件-分布式架构
分布式·架构·系统架构·分布式架构
zixu_star1 天前
从单机到分布式:定时任务如何处理大量数据与执行失败?
分布式
lsc_blog2 天前
听到优化风声,先准备能由自己掌控的事
数据库·分布式·中间件·职场和发展·重构
Lansonli3 天前
大数据Spark(八十七):Spark-Submit 参数详解
大数据·分布式·spark
qq_452396233 天前
第二篇:《CommitLog + ConsumeQueue:一条日志解决 Kafka 多分区随机写的难题》
分布式·kafka
Alluxio4 天前
Alluxio + OCI:为 AI 工作负载实现亚毫秒访问延迟与可扩展吞吐
运维·数据库·人工智能·分布式·缓存·ai·语言模型
阿卡好可爱4 天前
Lua 热更新不生效:改完文件线上仍是旧逻辑,package.loaded 与 upvalue 重绑定详解
数据结构·分布式·后端·架构·lua
我不会起名字3225 天前
消费回调固定 return nil:错误传播与 Kafka 位点提交的区别
后端·mongodb·kafka·go·im·故障排查
qq_452396235 天前
第十篇:《Kafka 安全加固:SASL、SSL、ACL 与多租户隔离》
安全·kafka·ssl