4. Kafka 数据安全治理:认证、授权、加密与审计

说到 Kafka 安全,很多团队一开始都觉得「我们跑在内网,没事」。嗯,我以前也这么想。直到有一次在客户现场做渗透测试,发现某个 Kafka 集群的 broker 端口直接暴露在公网,连 SASL 都没开,谁都能往 topic 里写数据。那之后我就养成了一个习惯:不管内网外网,安全配置先拉满。

这一章我们聊透 Kafka 的安全体系。说白了就四块:你是谁(认证)、你能干啥(授权)、数据别被偷看(加密)、出事了能查(审计)。

核心原则:安全不是某个单一配置,而是层层叠加的防御。缺一层,整个体系就可能被攻破。

Kafka 数据安全治理全景图 安全目标:机密性 · 完整性 · 可用性 认证 (SASL/SSL) 授权 (ACL) 加密 (TLS/SSL) 审计日志 认证机制 SASL/PLAIN SASL/SCRAM · SASL/GSSAPI SSL 双向认证 授权机制 Topic/Group/Cluster ACL 前缀匹配 · 通配符 超级用户 · 可插拔 Authorizer 数据加密 Broker 间 TLS 加密 Client-Broker TLS 加密 端到端应用层加密 审计 操作日志 请求日志 变更追踪 安全最佳实践:最小权限 · 分层防御 · 持续审计

4.1 认证机制:你是谁?

认证是安全的第一道门。Kafka 支持多种认证方式,我按推荐程度排个序:

认证方式 安全等级 复杂度 适用场景
SASL/SCRAM 高 中 生产环境首选,密码不存明文
SASL/PLAIN 低 低 仅用于开发测试,密码明文传输
SASL/GSSAPI (Kerberos) 极高 高 大型企业,已有 Kerberos 基础设施
SSL 双向认证 极高 高 需要证书链管理的场景

我个人习惯用 SASL/SCRAM。为什么?因为它把密码存在 ZooKeeper 里,用的是加盐哈希,不像 PLAIN 那样直接传明文。我在一个金融项目里就吃过 PLAIN 的亏——运维不小心开了 debug 日志,密码全打出来了。从那以后,PLAIN 我只在本地 Docker 里用。

配置示例:启用 SASL/SCRAM

# server.properties
listeners=SASL_PLAINTEXT://:9093
sasl.enabled.mechanisms=SCRAM-SHA-256
sasl.mechanism.inter.broker.protocol=SCRAM-SHA-256
authorizer.class.name=kafka.security.authorizer.AclAuthorizer

# 创建用户(在 broker 上执行)
kafka-configs.sh --zookeeper localhost:2181 \
  --alter --add-config 'SCRAM-SHA-256=[password=admin-secret]' \
  --entity-type users --entity-name admin

4.2 授权机制:你能干啥?

认证通过之后,接下来就是授权。Kafka 用 ACL(Access Control Lists) 来控制谁可以对什么资源做什么操作。

ACL 的格式看起来有点绕,其实核心就四个要素:

  • 主体(Principal):谁?比如 User:alice
  • 资源(Resource):对什么?比如 Topic:orders
  • 操作(Operation):干啥?比如 Read、Write
  • 权限类型(Permission Type):Allow 还是 Deny

举个例子,让用户 alice 只能读 orders 这个 topic:

kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 \
  --add --allow-principal User:alice \
  --operation Read --topic orders

我曾经踩过的坑:ACL 默认是白名单机制——没显式授权的,全部拒绝。但很多人不知道,--allow-principal 只加了一条 Allow 规则,如果之前有 Deny 规则,优先级更高。所以排查 ACL 问题时,记得用 --list 看全量规则。

另外,Kafka 有个「超级用户」的概念。配置了 super.users 的用户可以绕过所有 ACL 检查。我建议只在初始化集群时用,日常运维还是走普通用户+ACL,方便审计。

4.3 数据加密:别让数据裸奔

加密分两层:传输加密 和 存储加密。Kafka 原生支持传输加密(TLS/SSL),存储加密一般靠磁盘加密或应用层自己处理。

传输加密的配置其实不复杂,但证书管理才是大头。我见过一个团队,TLS 配好了,结果证书过期没人管,整个集群挂了半天。所以,证书自动续期一定要纳入运维流程。

加密层级 实现方式 保护范围 性能影响
Client-Broker TLS SSL 监听器 + 客户端信任证书 客户端到 Broker 的链路 中(握手开销)
Broker 间 TLS security.inter.broker.protocol=SSL Broker 之间的数据复制 中
端到端加密 应用层加密 Payload 数据从生产到消费全程加密 高(需自行管理密钥)

我的建议:如果合规要求不强制端到端加密,用 TLS 传输加密就够了。端到端加密虽然安全,但密钥分发、轮换、消费者解密都是额外负担。除非是金融交易或医疗数据,否则别给自己找麻烦。

4.4 审计日志:出了事能查

审计日志是安全的最后一道防线。Kafka 本身不提供开箱即用的审计日志,但我们可以通过几种方式实现:

  1. 开启请求日志:在 broker 的 log4j 配置里打开 kafka.request.logger,记录所有请求的客户端 IP、用户、操作。
  2. 使用 Audit Log Hook:Kafka 2.0+ 支持 Authorizer 接口的自定义实现,可以在授权检查时记录日志。
  3. 外部审计系统:把 ACL 变更、配置变更、用户操作都发到一个专门的审计 topic,用 ELK 或 Splunk 做分析。

我记得有一次排查数据泄露事件,就是靠审计日志里的客户端 IP 和操作时间,锁定了某个离职员工的账号还在用。从那以后,我们团队把审计日志的保留期从 30 天改成了 180 天。

开启请求日志的配置:

# log4j.properties
log4j.logger.kafka.request.logger=DEBUG, requestAppender
log4j.appender.requestAppender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.requestAppender.File=/var/log/kafka/request.log
log4j.appender.requestAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.requestAppender.layout.ConversionPattern=[%d] %p %m (%c)%n

4.5 安全最佳实践:我的经验清单

做了这么多年 Kafka 安全,我总结了几条铁律:

  • 最小权限原则:每个用户只给够用的权限。别图省事给个 --topic '*' --operation All,那是给自己挖坑。
  • 分层防御:认证 + 授权 + 加密 + 审计,缺一不可。少一层,攻击者就多一个突破口。
  • 定期轮换密钥:密码、证书、SCRAM 凭证,至少每 90 天换一次。自动化脚本安排上。
  • 监控安全事件:ACL 拒绝次数、认证失败次数、异常 IP 访问,这些指标要上告警。
  • 安全配置即代码:所有 ACL、用户、证书配置都走 GitOps,别手动敲命令。我见过太多「这个 ACL 是谁加的?不知道」的尴尬场面。

最后提醒一句:安全配置不是一次性的。每次版本升级、集群扩容、人员变动,都要重新审视安全策略。别等到出了事才想起来「哦,原来我们没开审计日志」。