4. 授权模型ACL
在 Kafka 的安全体系中,认证解决的是“你是谁”,而授权解决的是“你能做什么”。Kafka 的授权模型以 ACL(Access Control List,访问控制列表)为核心,通过一条条显式规则,把主体(Principal)、资源(Resource)、操作(Operation)和允许/拒绝(Allow/Deny)绑定在一起。理解 ACL 的语法结构,是后续用 CLI 精确管理权限的基础。
ACL 的语法结构
一条 Kafka ACL 由五个核心要素构成,可以概括为“谁,对什么资源,在什么条件下,能做什么,是允许还是拒绝”。在 CLI 中,这些要素通过参数表达:
- --allow-principal / --deny-principal:主体,格式为
User:用户名或Group:组名,例如User:alice。 - --operation:操作权限,如 Read、Write、Create、Delete、Alter、Describe、DescribeConfigs、AlterConfigs、IdempotentWrite、ClusterAction 等。
- --topic / --group / --cluster / --transactional-id / --delegation-token:资源类型与资源名。
- --resource-pattern-type:资源匹配模式,取值为
literal(精确匹配)或prefixed(前缀匹配)。 - --allow-host / --deny-host:来源主机,默认
*表示任意主机。
这五个要素共同决定了一条规则是否命中。Kafka 的授权判定遵循“显式拒绝优先、无匹配则拒绝”的原则:只要存在一条匹配的 Deny 规则,请求就被拒绝;如果没有 Allow 规则命中,同样被拒绝。因此 ACL 是白名单式的,默认关闭。
资源类型与操作权限的对应关系
不同资源类型支持的操作并不相同,混淆会导致 ACL 无效。Topic 资源常用 Read、Write、Create、Delete、Describe、DescribeConfigs、AlterConfigs;Group 资源常用 Read、Describe;Cluster 资源常用 Create、ClusterAction、Alter、Describe、DescribeConfigs、IdempotentWrite;TransactionalId 资源常用 Write、Describe。例如生产者向主题写入需要 Topic 的 Write,消费者读取需要 Topic 的 Read 以及对应 Group 的 Read。
通配符的使用
Kafka ACL 支持两种通配方式。第一种是资源名使用 *,表示匹配所有资源,例如 --topic "*" 表示所有主题。第二种是 --resource-pattern-type prefixed,配合资源名前缀,例如 --topic "app-" --resource-pattern-type prefixed 匹配所有以 app- 开头的主题。需要注意,* 与 prefixed 是两种不同机制:* 是字面量通配,prefixed 是前缀匹配。此外,--allow-host "*" 表示任意来源主机。
通配符虽然方便,但会放大权限范围。生产环境应优先使用精确资源名或受控前缀,避免对 * 授予 Write 或 Delete 这类高危操作。
通过 CLI 管理 ACL
Kafka 提供 kafka-acls.sh 脚本用于 ACL 的增删查。所有操作都需要指定 --bootstrap-server 和 --command-config(包含管理员认证信息)。下面以几个典型场景说明。
场景一:为生产者授予写入权限。允许用户 alice 向主题 orders 写入:
kafka-acls.sh --bootstrap-server broker1:9092 \
--command-config admin.properties \
--add --allow-principal User:alice \
--operation Write --topic orders
场景二:为消费者授予读取权限。消费者需要同时获得 Topic 的 Read 和 Group 的 Read:
kafka-acls.sh --bootstrap-server broker1:9092 \
--command-config admin.properties \
--add --allow-principal User:bob \
--operation Read --topic orders \
--operation Read --group order-consumer-group
场景三:使用前缀通配符。允许用户 carol 读取所有以 log- 开头的主题:
kafka-acls.sh --bootstrap-server broker1:9092 \
--command-config admin.properties \
--add --allow-principal User:carol \
--operation Read --topic "log-" \
--resource-pattern-type prefixed
场景四:查看与删除。列出某主题上的所有 ACL,然后删除其中一条:
kafka-acls.sh --bootstrap-server broker1:9092 \
--command-config admin.properties \
--list --topic orders
kafka-acls.sh --bootstrap-server broker1:9092 \
--command-config admin.properties \
--remove --allow-principal User:alice \
--operation Write --topic orders
实践中的判断依据
配置完成后,如何确认 ACL 生效?最直接的方式是用被授权主体发起一次真实操作,例如生产者发送一条消息、消费者拉取一条消息,观察是否抛出 TopicAuthorizationException 或 GroupAuthorizationException。如果被拒绝,先用 --list 检查 ACL 是否存在、资源名和 pattern-type 是否匹配、operation 是否覆盖了实际请求。常见错误包括:只给了 Topic Read 却忘了 Group Read;使用 prefixed 时资源名写成了完整主题名;以及 host 限制过严导致来源 IP 不匹配。
ACL 的管理本质上是“最小权限”与“可维护性”之间的平衡。通配符能减少规则数量,但会扩大攻击面;精确规则更安全,但数量增长后需要借助命名规范和定期审计来维护。建议为每类应用定义清晰的主体命名和资源前缀,把 ACL 变更纳入版本化配置,避免手工操作带来的遗漏。