1. kafka安全设置分类
1.1 消息加密SSL
将kafka消息使用SSL加密,类似于http到https的升级。可以避免通过网卡窃取到消息内容。但是SSL会导致kafka无法使用零拷贝特性,官方说法是降低性能9%左右。
1.2 访问认证SASL
生产者和消费者访问kafka需要用户名和密码认证。分为PLAIN、SCRAM、GSSAPI、OAUTHBEARER等,PLAIN的缺点是kafka集群启动后不能动态修改用户,修改需要重启,不大适合生产环境,SCRAM克服了这一缺点,GSSAPI则是使用额外的Kerberos组件,OAUTHBEARER主要支持Oauth场景。
1.3 权限控制ACL
为了避免某一服务误操作影响所有topic,可以对每个user添加acl,只能对指定的topic进行读或者写。
身份认证与访问控制主要涉及的是2和3。
2. kafka集群添加SCRAM认证
kafka集群的SCRAM认证并不会影响到zookeeper集群。 不论是裸机环境还是容器中的kafka集群,改造主要分为三部分。
2.1 添加scram_jaas文件
文件内容为加密方式,使用超级管理员用户和密码。因为其他用户还没有设置权限,默认是没有任何权限,所以无法读写任何topic。
KafkaServer {
org.apache.kafka.common.security.scram.ScramLoginModule required
username="admin"
password="xxxxx";
};
注意,这里配置的admin用户具有所有权限,不需要后面继续配置,其他用户如果不配置权限,默认没有任何权限,执行任何写入或者访问操作都会报错,所以我们在下面执行配置操作的时候都是用这个admin用户。
另外,scram使用的是org.apache.kafka.common.security.scram.ScramLoginModule
,还有一种org.apache.kafka.common.security.plain.PlainLoginModule
对应的就是普通的SASL加密,不能动态修改用户的那个。
2.2 修改kafka启动脚本
目的是启动时加载2.1添加的文件。
修改kafka-server-start.sh脚本,将最后一行替换为
exec $base_dir/kafka-run-class.sh $EXTRA_ARGS -Djava.security.auth.login.config=$base_dir/../config/kafka_server_scram_jaas.conf kafka.Kafka "$@"
其中的kafka_server_scram_jaas.conf文件就是上面的文件,注意路径要写对,换成你自己的文件路径。这是一种方法。
还可以设置环境变量
KAFKA_PLAIN_PARAMS="-Djava.security.auth.login.config=/kafka_2.13-2.6.0/config/kafka_server_scram_jaas.conf"
KAFKA_OPTS="$KAFKA_PLAIN_PARAMS $KAFKA_OPTS"
这种方法在制作docker镜像或者使用k8s部署kafka的时候比较方便,直接在Dockerfile文件添加
ENV KAFKA_PLAIN_PARAMS="-Djava.security.auth.login.config=/kafka_2.13-2.6.0/config/kafka_server_scram_jaas.conf"
ENV KAFKA_OPTS="$KAFKA_PLAIN_PARAMS $KAFKA_OPTS"
2.3 修改配置文件server.properties
加上scram相关设置 主要是listeners需要把
listeners=PLAINTEXT://localhost:9092
修改为
listeners=SASL_PLAINTEXT://10.95.123.66:9092
并在文件末尾添加
security.inter.broker.protocol=SASL_PLAINTEXT
sasl.mechanism.inter.broker.protocol=SCRAM-SHA-256
sasl.enabled.mechanisms=SCRAM-SHA-256
allow.everyone.if.no.acl.found=false
super.users=User:admin
authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer
以上三步修改好,直接启动kafka集群。
3. 权限设置
3.1 添加用户
分别添加管理员用户和普通用户,信息写入zookeeper
./kafka-configs.sh --zookeeper ip:port --alter --add-config 'SCRAM-SHA-256=[password=xxx],SCRAM-SHA-512=[password=xxx]' --entity-type users --entity-name xxx
./kafka-configs.sh --zookeeper ip:port --alter --add-config 'SCRAM-SHA-256=[iterations=8192,password=xxx],SCRAM-SHA-512=[password=xxx]' --entity-type users --entity-name xxx
用户信息存在zookeeper,这就是SCRAM能动态修改用户的原因。
3.2 测试访问
同上面一样创建kafka_client_scram_jaas.conf文件,只不过这个文件是给客户端访问kafka使用的,里面填上用户名名和密码。与kafka_server_scram_jaas.conf他们的主要区别是```
KafkaServer和KafkaClient两个词。
KafkaClient {
org.apache.kafka.common.security.scram.ScramLoginModule required
username="xxxxx"
password="xxxxx";
};
分别修改kafka-console-producer.sh
和kafka-console-consumer.sh
文件的最后一行
exec $(dirname $0)/kafka-run-class.sh -Djava.security.auth.login.config=/usr/local/kafka_2.13-2.6.0/bin/kafka_client_scram_jaas.conf kafka.tools.ConsoleProducer "$@"
exec $(dirname $0)/kafka-run-class.sh -Djava.security.auth.login.config=/usr/local/kafka_2.13-2.6.0/bin/kafka_client_scram_jaas.conf kafka.tools.ConsoleConsumer "$@"
创建client.properties文件:
security.protocol=SASL_PLAINTEXT
sasl.mechanism=SCRAM-SHA-256
分别执行
./kafka-console-producer.sh --broker-list 10.95.123.66:9092 --topic test --producer.config ./client.properties
./kafka-console-consumer.sh --bootstrap-server 10.95.123.66:9092 --topic test --from-beginning --consumer.config ./client.properties
就可以在producer侧输入,从consumer侧看到输出。
3.3 acl设置
没有配置acl权限的用户默认是不能访问任何topic的(admin用户可以访问所有),下面是赋予读写权限的操作
./kafka-acls.sh --authorizer kafka.security.auth.SimpleAclAuthorizer --authorizer-properties zookeeper.connect=ip:port --add --allow-principal User:xxx --operation Read --topic xxx
./kafka-acls.sh --authorizer kafka.security.auth.SimpleAclAuthorizer --authorizer-properties zookeeper.connect=ip:port --add --allow-principal User:xxx --operation Write --topic xxx
查看权限设置列表
./kafka-acls.sh --authorizer kafka.security.auth.SimpleAclAuthorizer --authorizer-properties zookeeper.connect=ip:port --list