【概述】


通常情况下,Kafka部署后都是自己的业务进行生产消费,但也有一些情况,比如通过kafka和第三方对接,甚至是多个三方对接;或者是多用户使用同一套kafka集群,各自使用不同的topic。在这种场景下,一般不希望不同的用户能访问彼此的数据,因此需要进行权限控制,这就会用到Kafka中的ACL。

Kafka中的ACL定义为:来自指定主机(Host)的指定用户(User)对任意资源(Resource)的操作(Operation)是否符合指定的资源模式(ResourcePattern)。默认情况下是不开启的,通过在配置文件中增加如下配置项,则启用了kafka的ACL机制。

authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer

kafka中的ACL模块是以插件化的形式存在的,除了自带默认的实现外,可以较容易的引入外部插件实现权限控制,例如ranger、santry。

【kafka中的资源与对应操作】


上面提到了ACL定义本质上是对指定资源的指定操作的访问控制,在kafka中的资源包括主题(Topic)、消费者组(ConsumerGroup)、集群(Cluster)、事务(ClusterID)以及委派token(DelegationToken)。对我们而言,最常用的则是主题、消费者组和集群。

对于topic涉及的操作包括:

操作 

描述

Write

向topic发送消息

Read

从topic消费消息

Create

创建topic

Delete

删除topic

Describe

获取topic的描述信息,例如分区信息,分区leader信息等(生产/消费都需要该消息)

DescribeConfigs

获取topic的配置信息(常用于kafkaAdmin)

Alter

改变topic的描述信息(例如创建新分区)

AlterConfigs

修改topic的配置信息

对于消费者组涉及的操作包括:

操作

描述

Read

加入、离开、同步消费者组,提交偏移等

Describe

查询消费者组的情况,例如查看有哪些消费者组,消费者组的偏移位置等

Delete

删除消费者组

对于集群涉及的操作包括:

操作

描述

ClusterAction

follow从leader获取分区信息、副本同步、集群关闭等操作需要该权限

IdempotentWrite

幂等发送

Create

(自动)创建topic操作需要改权限

Describe

涉及罗列消费者组等操作

Alter

(kafkaAdmin)创建、删除ACL

AlterConfigs

修改配置项的值

注:kafka自身需要有对cluster的各种访问权限,尤其是ClusterAction,这个涉及分区leader选举、ISR同步等等操作,可以理解为生产消费的基础,否则即便给用户配置了read、write、describe权限,仍旧是无法正常生产消费的。

【ACL的增删查改】


知道了kafka中的资源以及对应的操作后,剩下的就是对ACL的增删查了。这些操作都是通过"kafka-acls.sh"脚本来完成的,命令使用方式为:

kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:xxx --alow-host xxx --operation xxx --topic/cluster/group/delegation-token/transactional-id
# --authorizer-properties 为必填项, 后面的值以K=V形式体现, 当前仅能配置zookeeper.connect指定zk的地址
# --add 添加acl 或者 --remove 删除acl 或者 --list 罗列acl
# --allow-principal 指定用户, 用户格式为User:xxx, 其中xxx为具体的用户名
# --allow-host 指定主机地址
# --operation 指定操作
# --topic 指定topic
# --cluster 指定集群
# --group 指定消费者组

例如,添加允许用户hncscwc(不限定主机)在名为bigdata的topic上进行生产的命令为:

kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:hncscwc --operation Write --operation Describe --topic bigdata

效果如下所示:

kafka认证方式 kafka权限认证acl_kafka

进行消息生产的验证:

kafka认证方式 kafka权限认证acl_kafka_02


同样,如果需要允许该用户在指定topic上进行消费,除了需要为topic资源配置ACL以外,还需要为group配置资源。kafka为了简化操作,在kafka-acls.sh脚本中提供了"--consumer"参数,通过该参数会自动对topic与group进行配置,同样还包括"--producer"参数。

kafka认证方式 kafka权限认证acl_java_03

注1:使用"--consumer",需要同时通过"--topic"、"--group"分别指定主题和消费者组

注2:通配符*需要加''

默认情况下,不在指定ACL的非超级用户的操作都是没有权限的,可以通过如下配置修改默认行为,即默认使其具有操作权限。

allow.everyone.if.no.acl.found=true

另外,配置超级用户的方式为:

super.users=User:xxx;User:xxx

【运行机制】


从上面的使用介绍中可以知道,kafka的acl使用还是相对比较简单的,具体的实现逻辑如下图所示:

kafka认证方式 kafka权限认证acl_linux_04

首先通过"kafka-acls.sh"脚本增加删除ACL的操作,本质是与ACL进行交互,并将信息写入对应的znode中,也就是说kafka的acl信息是存储在zookeeper中的。

具体为指定根节点下,名为kafka-acl的znode,在这个下面分别存储了Topic、Group、Cluster等资源的ACL信息。

kafka认证方式 kafka权限认证acl_linux_05

注:从这个流程可以看出,为什么一定要指定"--authorizer-properties"参数。

其次,"kafka-acls.sh"脚本向zookeeper写入ACL信息后,还会写入另外一个znode信息:"kafka-acl-changes",通过以版本号递增的形式写入改动的资源项。

kafka认证方式 kafka权限认证acl_数据库_06

而kafka broker则watch该节点,以知晓acl的新增删除等变更情况。一旦知道acl有变更,重新从zookeeper中读取资源的acl信息,并更新内存中的记录信息。此后,客户端进行生产消费时则可以进行权限校验。

【总结】


小结一下,本文简要概述了Kafka中的访问控制,如何配置,如何增删查ACL,以及背后的实现逻辑。而所有这一切的一个前提,也是本文没有提到的:kafka需要开启认证(通常是kerberos认证),这样kafka才能正确感知客户端的用户信息,也就才能正确地进行访问控制。另外,在对资源进行配置时,还可以进行一些表达式的匹配来进行灵活控制,详细可以查看官网文档。