目录
认证
sasl与ssl
做 SSL 认证.要启用双路认证,也就是说 Broker 也要认证客户端的证书。
kafka支持sasl机制有5种
- gssapi:kerberos的安全接口
- plain:简单用户名/密码认证
- scram:解决plain机制安全问题的新机制
- oauthbearer:基于oauth2认证框架的机制
- delegation token:补充现有sasl机制的轻量级认证机制
比较
使用 SSL 做信道加密的情况更多一些,但使用 SSL 实现认证不如使用 SASL。毕竟,SASL 能够支持你选择不同的实现机制,如 GSSAPI、SCRAM、PLAIN 等。因此,我的建议是你可以使用 SSL 来做通信加密,使用 SASL 来做 Kafka 的认证实现。
适用场景
gssapi
SASL/GSSAPI 主要是给 Kerberos 使用的。如果你的公司已经做了 Kerberos 认证(比如使用 Active Directory),那么使用 GSSAPI 是最方便的了。因为你不需要额外地搭建 Kerberos,只要让你们的 Kerberos 管理员给每个 Broker 和要访问 Kafka 集群的操作系统用户申请 principal 就好了。总之,GSSAPI 适用于本身已经做了 Kerberos 认证的场景,这样的话,SASL/GSSAPI 可以实现无缝集成。
plain
它是一个简单的用户名 / 密码认证机制,通常与 SSL 加密搭配使用。注意,这里的 PLAIN 和 PLAINTEXT 是两回事。PLAIN 在这里是一种认证机制,而 PLAINTEXT 说的是未使用 SSL 时的明文传输。对于一些小公司而言,搭建公司级的 Kerberos 可能并没有什么必要,他们的用户系统也不复杂,特别是访问 Kafka 集群的用户可能不是很多。对于 SASL/PLAIN 而言,这就是一个非常合适的应用场景。总体来说,SASL/PLAIN 的配置和运维成本相对较小,适合于小型公司中的 Kafka 集群。
但是,SASL/PLAIN 有这样一个弊端:它不能动态地增减认证用户,你必须重启 Kafka 集群才能令变更生效。为什么呢?这是因为所有认证用户信息全部保存在静态文件中,所以只能重启 Broker,才能重新加载变更后的静态文件。
scram
通过将认证用户信息保存在 ZooKeeper 的方式,避免了动态修改需要重启 Broker 的弊端。在实际使用过程中,你可以使用 Kafka 提供的命令动态地创建和删除用户,无需重启整个集群。因此,如果你打算使用 SASL/PLAIN,不妨改用 SASL/SCRAM 试试。
配置实例
admin 用户、writer 用户和 reader 用户。admin 用户用于实现 Broker 间通信,writer 用户用于生产消息,reader 用户用于消费消息。
- 创建用户
1 | $ cd kafka_2.12-2.3.0/ |
- 创建jaas文件
1 |
|
- 不要忘记最后一行和倒数第二行结尾处的分号;
- JAAS 文件中不需要任何空格键。
配置broker参数
1 | # 开启 SCRAM 认证机制,并启用 SHA-256 算法; |
- 启动broker
1 |
|
- 发送消息
创建配置文件producer.conf
1 | security.protocol=SASL_PLAINTEXT |
发送消息
1 |
|
- 消费消息
创建配置consumer.conf消费消息1
2
3
4
security.protocol=SASL_PLAINTEXT
sasl.mechanism=SCRAM-SHA-256
sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="reader" password="reader";1
2
3
$ bin/kafka-console-consumer.sh --bootstrap-server localhost:9092,localhost:9093 --topic test --from-beginning --consumer.config <your_path>/consumer.conf
hello, world - 动态增减用户
1 |
|
oauthbearer
主要是为了实现与 OAuth 2 框架的集成。Kafka 不提倡单纯使用 OAUTHBEARER,因为它生成的不安全的 JSON Web Token,必须配以 SSL 加密才能用在生产环境中
delegation
主要目的是补充现有的 SASL 或 SSL 认证。如果要使用 Delegation Token,你需要先配置好 SASL 认证,然后再利用 Kafka 提供的 API 去获取对应的 Delegation Token。这样,Broker 和客户端在做认证的时候,可以直接使用这个 token,不用每次都去 KDC 获取对应的 ticket(Kerberos 认证)或传输 Keystore 文件(SSL 认证)。
授权
授权:对信息安全或计算机安全相关的资源授予访问权限,特别是存取控制
kafka使用的ACL
常见的四种控制权限:
ACL:access-control list,访问控制列表
用户与权限的直接映射关系
用户–>权限RBAC:role-based access control,基于角色的权限控制
用户–>角色–>权限ABAC:attribute-based control,基于属性的权限控制
- PBAC:policy-based access control,基于策略的权限控制
kafka的acl
Principal P is [Allowed/Denied] Operation O From Host H On Resource R.
- principal:kafka集群的用户
- operation:具体的访问类型
- host:链接kafka集群的客户端应用ip地址,host支持星号占位符
- resource:kafka资源类型,topic,cluster,group,transactionalid,delegationtoken
开启acl
kafka提供了一个可插拔的授权实现机制,所有的acl配置项保存在zk的/kafka-acl节点中.可以通过kafka-acls脚本动态的对acl项进行增删改查
开启acl,在broker的配置文件(server.properties)种增加
1 | authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer |
authorizer.class.name 参数指定了 ACL 授权机制的实现类。当前 Kafka 提供了 Authorizer 接口,允许你实现你自己的授权机制,但更常见的做法,还是直接使用 Kafka 自带的 SimpleAclAuthorizer 实现类。一旦设置好这个参数的值,并且启动 Broker 后,该 Broker 就默认开启了 ACL 授权验证。在实际生产环境中,你需要为集群中的每台 Broker 都做此设置。
超级用户
开启acl之后,需要显示地为不同用户设置访问某项资源的权限,否则,在默认情况下,没有配置的任何acl的资源是不能被访问的,不过超级用户能够访问所有资源,在server.properties种配置
1 | super.users=User:super1;User:super2 |
如果你要一次性指定多个超级用户,那么分隔符是分号而不是逗号,这是为了避免出现用户名中包含逗号从而无法分割的问题。
kafka-acls
1 | # All 表示所有操作,topic 中的星号则表示所有主题,指定 --cluster 则说明我们要为 Alice 设置的是集群权限。 |
授权机制的单独使用
授权机制脱离认证机制单独使用,不过只能针对ip.
简单示例
1 |
|
配置ssl
broker配置
1 |
|
该脚本主要的产出是 4 个文件,分别是:server.keystore.jks、server.truststore.jks、client.keystore.jks 和 client.truststore.jks。
需要把以 server 开头的两个文件,拷贝到集群中的所有 Broker 机器上,把以 client 开头的两个文件,拷贝到所有要连接 Kafka 集群的客户端应用程序机器上。
配置每个 Broker 的 server.properties 文件,增加以下内容:
1 |
|
客户端配置
创建client-ssl.config
1 |
|
测试
1 | $ bin/kafka-console-producer.sh --broker-list localhost:9093 --topic test --producer.config client-ssl.config |
最佳实践
- 开启acl
- 采用白名单机制
不要设置:allow.everyone.if.no.acl.found=true。 - 使用kafka-acls脚本为ssl用户授予集群权限
配置ssl时,指定用户的 Distinguished Name 为“CN=Xi Hu, OU=YourDept, O=YourCompany, L=Beijing, ST=Beijing, C=CN”。之前在设置 Broker 端参数时,我们指定了 security.inter.broker.protocol=SSL,即强制指定 Broker 间的通讯也采用 SSL 加密。
如果不为指定的 Distinguished Name 授予集群操作的权限,你是无法成功启动 Broker 的。因此,你需要在启动 Broker 之前执行下面的命令:1
2
$ bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:"CN=Xi Hu,OU=YourDept,O=YourCompany,L=Beijing,ST=Beijing,C=CN" --operation All --cluster - 为客户端程序授予相应的权限
1
2
3
4
5
$ bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:"CN=Xi Hu,OU=YourDept,O=YourCompany,L=Beijing,ST=Beijing,C=CN" --producer --topic 'test'
$ bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:"CN=Xi Hu,OU=YourDept,O=YourCompany,L=Beijing,ST=Beijing,C=CN" --consumer --topic 'test' --group '*'
授予的权限越少,kafka集群越安全