1 背景
所在的团队里,遇到了这样的一个问题。团队自身搭建的kafka集群被别的团队使用了,而且还不知道 是哪个团队在使用。具体表现为 莫名其妙的出现了非自身业务的topic,而这些topic里的数据看起来,还是蛮正式的业务数据。你还不能把这些topic删除了,topic删除了就影响到正式业务了,这属于人为造成的,肯定会被追责。
心理真不是滋味,团队硬件资源和软件资源被别人白嫖了,并且还不知道是被谁白嫖的。
从历史的经验和过程,小小的进行了一番反思,为什么会出现这样一种现象和炒蛋的情况了?
- 需求层面不重视 : 安全属于非功能性需求,不属于业务人员关心的业务指标,在没有被外界暴露并上升为新闻热点时,领导不关心,但一出问题却是非常严重的PO级事故,特别是IT领导此时会瑟瑟发抖,每2个小时一通电话的询问,那都是关心的不频繁了。
- 安全意识缺失 : 日常开发和运维人员不具备或者较少的关注安全这块。完成了业务功能研发,已经对得起这份工资了,为什么还要去做这种费力不讨好的事了。
- 需求优先级 : 紧急的业务需求,都会排在前面先研发;把安全这块排在了后面,到最后不了了之。因为做和不做,在没暴雷之前,对业务来说收益都不大,做了说不定还影响到线上正常业务,"得不偿失"
- 软件层面先天的缺失 : kafka默认配置里是没有进行安全方面的配置
在下定决心要去解决kafka安全问题,外加查看kafka官方的英文文档+实践后,整理了以下资料。 主要是kafka的安全模型+实践(照着做步骤)
2 概念模型:在kafka里,安全模型包含三个点
kafka的安全模型认证,基本上是围绕kafka的架构模型展开的,主要从三个点进行安全模型的打造。
第一:客户端连接kafka的连接认证
第二:使用kafka功能的相关权限认证
第三:客户端和kafka通信的加密
第一点:认证
认证在生活中类似于小区的门禁;只有事先录入了指纹或者人脸才能打开小区的大门。在常用的软件里类似于web网页端的登录功能,你是否是一个合法的用户,只有进行了登录验证才知道。
认证主要解决了什么问题?
在kafka里认证主要解决的是连接的合法性问题
- 生产者和消费者是否能连接到kafka broker?主要是验证连接的合法性
- 一个broker是否能加入broker集群里,互相之间进行通信?还是验证连接的合法性
- broker是否能连接到zk?还是验证连接的合法性
kafka的认证机制有哪些了?
kafka提供的认证机制主要有两种,一种是SSL,一种是SASL。 但是SASL下又有很多种变种的认证方式。比如SASL/GSSAPI,SASL/PLAIN,SASL/SCRAM-SHA-256 and SASL/SCRAM-SHA-512,SASL/OAUTHBEARER。
认证机制这么多我该选择哪一种了?
各种认证类型的使用场景,优缺点,见下表。
选择那种认证方案,依据个人所处的场景和环境进行选择。如果某一种认证机制不满足你,kafka还允许组合的使用这些认证机制。这里不详讲。
第二点:功能权限
打开了小区的门,然后你可以在小区里闲逛,也能开门,但只能开自家的门,其他邻居的门,是打不开的(当然非法手段除外)。 和常用的软件相比,类似于管理后台的菜单权限功能,不同的用户登录同一个管理后台后,看到的和能操作的功能是不一样的。
kafka里的权限解决了什么问题?
kafka功能权限主要解决的是:哪个用户能对什么样的资源进行什么操作;这种方式属于ACL模型的权限管理;和日常使用的管理后台,用的基于角色的权限管理(RBAC)还是有区别的。
在kafka0.10.2版本里资源有3种: 分别是cluster,topic、group。( 在最新的3.4.x版本里资源有5中,分别是cluster,topic、、group,transactional-id,delegation-token )
操作: 表示一个具体的操作类型。比如创建主题,删除主题,生产消息,消费消息等操作
第三点:通信的加密
对于和kafka broker进行通信的生产端,客户端,或者其它工具,kafka提供了SSL机制来解决通信的加密问题。这块不详见,因为我们遇到的大多数场景:kafka还是部署在内网,直接暴露在外网的还是比较少见,并且使用了SSL,在消息量比较大时,频繁的加解密也会带来性能的下降。但如果你的场景是在外网使用,或者传输一些交易级别,或者机密业务数据时,该用还是的用。
3 SASL/SCRAM认证 配置步骤
步骤1:创建用户
在kafka服务端执行以下创建用户脚本(注意:XXXIP替换为自己的zk地址)
bash
bin/kafka-configs.sh --zookeeper XXXIP:2181 --alter --add-config 'SCRAM-SHA-256=[iterations=8192,password=admin-secret],SCRAM-SHA-512=[password=admin-secret]' --entity-type users --entity-name admin
上面脚本创建了一个用户名为admin,密码为admin-secret的用户。 如果再想创建用户用于生产者或者消费者端使用,把admin和admin-secret替换即可。比如在创建个用户名为order-producer,密码为order-producer-secret的用户。
bash
bin/kafka-configs.sh --zookeeper XXXIP:2181 --alter --add-config 'SCRAM-SHA-256=[iterations=8192,password=order-producer-secret],SCRAM-SHA-512=[password=order-producer-secret]' --entity-type users --entity-name order-producer
步骤2: broker端配置
1. 配置broker间通信的用户认证信息到JAAS 文件里 把以下信息放到/etc/kafka/kafka_server_jaas.conf文件里。文件目录可自定义
ini
KafkaServer {
org.apache.kafka.common.security.scram.ScramLoginModule required
username="admin"
password="admin-secret"
};
2. 开启SASL/SCRAM认证 在Broker的server.properties 配置文件里,修改或加入以下配置
ini
sasl.enabled.mechanisms=SCRAM-SHA-256 (or SCRAM-SHA-512)
sasl.mechanism.inter.broker.protocol=SCRAM-SHA-256 (or SCRAM-SHA-512)
security.inter.broker.protocol=SASL_PLAINTEXT
listeners=SASL_PLAINTEXT://host.name:9092
第一行表示:开启SCRAM认证机制,并启动SHA-256算法。觉得算法安全强度不够,可升级到(SCRAM-SHA-512) 第二行表示:内部通信机制也是使用SCRAM,并用SHA-256算法 第三行表示:在broker间通信使用的安全协议是SASL_PLAINTEXT 第四行表示:broker监听端口,host,和使用的通信协议。
3. 重启broker 在重启时增加jvm 启动参数,以指定第一步创建的JAAS文件地址。
ini
-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
步骤3:消费者代码里,增加SCRAM和用户信息
java
consumerConfigMap.put("bootstrap.servers","XXX");
consumerConfigMap.put("enable.auto.commit",false);
consumerConfigMap.put("security.protocol","SASL_PLAINTEXT");
consumerConfigMap.put("sasl.mechanism","SCRAM-SHA-256");
consumerConfigMap.put("sasl.jaas.config","org.apache.kafka.common.security.plain.PlainLoginModule required username=\"order-producer\" password=\"order-producer-secret\";");
注意第三行到第五行。 只需要替换第五行里的用户名和密码即可。
步骤4:验证启动是否成功
Successfully logged in
消费端日志里,呈现出上面日志,标识认证成功。
4 功能权限 配置步骤
步骤1:kakfa 开启功能权限
kafka默认是不开启功能权限的,这也是kafka宣称的权限插件是可配置的表现之一。如果要开启,需要在broker配置文件server.properties里增加如下配置
ini
authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer
步骤2:很任性,想拥有一个超级用户,具有所有权限(可选)
broker配置文件server.properties里增加如下配置
ini
super.users=User:Bob;User:Alice
增加了两个超级用户Bob和Alice。 或者让所有用户都具有超级用户权限(不建议)
ini
allow.everyone.if.no.acl.found=true
PS:broker端配置修改后,记得重启
步骤3:针对生产者场景:指定某个用户,允许哪些IP地址访问,并能往指定的topic 发送消息
broker端执行以下脚本
ini
bin/kafka-acls.sh --authorizer-properties zookeeper.connect=XXX:2181 --add --allow-principal User:Bob --allow-principal User:Alice --allow-host 198.51.100.0 --allow-host 198.51.100.1 --operation Read --operation Write --topic Test-topic
指定用户Bob,和Alice 允许从 198.51.100.0和198.51.100.1的生产者机器上,往主题 Test-topic 发送消息
步骤4:针对消费者场景:指定某个用户,哪些IP地址,能在固定topic 固定消费组上 消费消息
broker端执行以下脚本
csharp
bin/kafka-acls.sh --authorizer-properties zookeeper.connect=XXX:2181 --add --allow-principal User:Bob --allow-host 198.51.100.2 --consumer --topic test-topic --group Group-1
指定用户Bob,允许从198.51.100.2的消费者机器上 消费topic为test-topic,并且消费组的名字必须是Group-1
5 总结
kafka对于安全方面提供了三个选型进行加固,是不是都要选?
我的回答是,根据自身业务场景和实际的环境进行选择。但如果你使用的kafka 是在0.10.2.0版本及以上,并且不想让的kafka集群在公司内裸奔的运行;并且被白嫖;建议至少开启SASL/SCRAM认证;简单的几步,就让你的集群拥有了基本的安全防护。
如果你不想在运维kafka集群时候,莫名其妙的出现一些topic;或者手一抖,集群被重启;那么在认证的基础上建议加上权限管理;简单的一行脚本设置,就让你拥有了kafka的功能权限。
原创不易,请 点赞,留言,关注,转载 4暴击^^
参考资料:
kafka.apache.org/20/document... kafka2.0 官方文档
kafka.apache.org/documentati... kafka 0.10.2官方文档
kafka.apache.org/documentati... kafka 3.4.x官方文档