之前写过一篇Kafka ACL使用实战,里面演示了如何配置SASL PLAIN + ACL来为Kafka集群提供认证/权限安全保障,但有一个问题经常被问到:这种方案下是否支持动态增加/移除认证用户——这里给出明确的答案:不可以!因为所有认证用户信息全部配置在静态的jaas文件中,故无法在不重启broker的情况下实现用户增减。这一次我以Kafka 2.1.0版本为例演示配置SASL SCRAM + ACL来实现如何动态增减用户,另外也想完善和优化上一篇中的一些不足之处(比如说不用再修改初始的.sh脚本,改用环境变量的方式来使设置生效)。

1. 环境准备

Kafka服务器:一台云主机,4 core,8GB RAM,1Gbps带宽

Kafka客户端:另一台云主机

客户端与服务器通过内网交互

2. 集群拓扑

启动两台Kafka服务器,由于我只在一台云主机上演示,故上面启动两个broker实例。客户端这边使用console-producer和console-consumer脚本来模拟客户端程序。

3. 创建用户

  我们使用kafka-configs.sh来创建用户,Kafka的SCRAM实现机制会把用户认证信息保存在Zookeeper中。假设我要创建3个用户admin, writer, reader分别用于实现Kafka broker间通讯、生产消息和消费消息。下面我们开始具体的配置:首先启动Zookeeper,但不要启动Kafka broker,ZK启动成功后执行以下命令去创建3个用户:

创建writer用户,密码是writer-pwd:

$ bin/kafka-configs.sh --zookeeper 172.21.0.9:2181 --alter --add-config 'SCRAM-SHA-256=[iterations=8192,password=writer-pwd],SCRAM-SHA-512=[password=writer-pwd]' --entity-type users --entity-name writer

Completed Updating config for entity: user-principal 'writer'.

创建reader用户,密码是reader-pwd:

$ bin/kafka-configs.sh --zookeeper 172.21.0.9:2181 --alter --add-config 'SCRAM-SHA-256=[password=reader-pwd],SCRAM-SHA-512=[password=reader-pwd]' --entity-type users --entity-name reader
Completed Updating config for entity: user-principal 'reader'.

创建admin用户,密码是admin:

$ bin/kafka-configs.sh --zookeeper 172.21.0.9:2181 --alter --add-config 'SCRAM-SHA-256=[password=admin],SCRAM-SHA-512=[password=admin]' --entity-type users --entity-name admin
Completed Updating config for entity: user-principal 'admin'.

3个测试用户都创建好了,下面我们使用kafka-configs.sh查看一下writer用户的信息:

$ bin/kafka-configs.sh --zookeeper 172.21.0.9:2181 --describe --entity-type users --entity-name writer
Configs for user-principal 'writer' are SCRAM-SHA-512=salt=dTlvNzl4Y3BvZ3BuMmx5ODY0aWlzN2RsZg==,stored_key=Yc02SwxDkAKDQH01W98bkJLJcVO24q9vR5tS0nWaq5Jg2Z7DtzwrOt6J2Cr8Oib+dHq7TUIeG+NLiCAMnRlfVg==,server_key=Tu+iiosvJrDemOvjaDdzrh2GhLRg6r9zoTRDdvXZCMA7n7+D8DYsUz6Gnugcczsnz5Ut/jkkklEOXYRXIqOLCg==,iterations=4096,SCRAM-SHA-256=salt=Y2dpcnB4aTU5NWNwMDZjNmFvbHluMWJpOQ==,stored_key=GGMhtO1PhxZFpEHOaDiqA4AM16Ma19nky1UV/gFoC1s=,server_key=L0R1xkcULaWcGMu6TdtWi5mf5lu1VTS8imWvKPlM3i4=,iterations=8192

里面包含了writer用户加密算法SCRAM-SHA-256以及SCRAM-SHA-512对应的盐值(salt)、ServerKey和StoreKey等,总之都是SCRAM机制的术语了。

4. Broker端配置

  和SASL PLAIN一样,我们依然需要为每个broker创建一个对应的jaas文件。注:由于本例中我的两个broker实例都是在同一台云主机上启动的,故我只创建一份jaas文件即可。实际使用中需要为每台单独的物理broker机器创建一份jaas文件。

KafkaServer {
org.apache.kafka.common.security.scram.ScramLoginModule required
username="admin"
password="admin";
};

将上面内容保存成kafka-broker-jaas.conf文件。注意末尾的两个分号,另外不要任何空白键。这里配置admin用户用于实现broker间的通讯。接下来是配置broker端的server.properties,配置项如下:

# 启用ACL
authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer

# 设置本例中admin为超级用户
super.users=User:admin

# 启用SCRAM机制,采用SCRAM-SHA-512算法

sasl.enabled.mechanisms=SCRAM-SHA-512

# 为broker间通讯开启SCRAM机制,采用SCRAM-SHA-512算法

sasl.mechanism.inter.broker.protocol=SCRAM-SHA-512

# broker间通讯使用PLAINTEXT,本例中不演示SSL配置
security.inter.broker.protocol=SASL_PLAINTEXT

# 配置listeners使用SASL_PLAINTEXT

listeners=SASL_PLAINTEXT://172.21.0.9:9092

# 配置advertised.listeners

advertised.listeners=SASL_PLAINTEXT://172.21.0.9:9092

  另一台broker的配置和它基本类似,只是要使用不同的端口(比如9093)、broker.id和log.dirs。现在分别启动两个broker实例,如果一切配置正常,这两个broker实例应该能够正常启动——注意引入jaas文件的方式,将-Djava.security.auth.login.config作为KAKFA_OPTS环境变量的方式进行设置。

$ KAFKA_OPTS=-Djava.security.auth.login.config=/xfs/bigdata/kafka_2.12-2.1.0/kafka-broker-jaas.conf bin/kafka-server-start.sh /xfs/bigdata/kafka_2.12-2.1.0/config/server1.properties
......

[2019-02-05 17:12:08,365] INFO Kafka version : 2.1.0 (org.apache.kafka.common.utils.AppInfoParser)
[2019-01-05 17:12:08,365] INFO Kafka commitId : 809be928f1ae004e (org.apache.kafka.common.utils.AppInfoParser)
[2019-02-05 17:12:08,367] INFO [KafkaServer id=0] started (kafka.server.KafkaServer)

$ KAFKA_OPTS=-Djava.security.auth.login.config=/xfs/bigdata/kafka_2.12-2.1.0/kafka-broker-jaas.conf bin/kafka-server-start.sh /xfs/bigdata/kafka_2.12-2.1.0/config/server2.properties
......

[2019-02-05 17:22:12,970] INFO Kafka version : 2.1.0 (org.apache.kafka.common.utils.AppInfoParser)
[2019-02-05 17:22:12,970] INFO Kafka commitId : 809be928f1ae004e (org.apache.kafka.common.utils.AppInfoParser)
[2019-02-05 17:22:12,971] INFO [KafkaServer id=1] started (kafka.server.KafkaServer)

现在创建测试topic,本例只创建一个单分区单副本的topic即可:

$ bin/kafka-topics.sh --create --zookeeper 172.21.0.9:2181 --topic test --partitions 1 --replication-factor 1
Created topic "test".

5. Client端配置 

  Okay,一切准备就绪了。我们先来使用console-producer脚本来尝试发送消息:

$ bin/kafka-console-producer.sh --broker-list 172.21.0.9:9092,172.21.0.9:9093 --topic test
>hello, world
[2019-02-05 18:17:19,005] ERROR Error when sending message to topic test with key: null, value: 12 bytes with error: (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
org.apache.kafka.common.errors.TimeoutException: Failed to update metadata after 60000 ms.

消息发送失败了,原因是没有指定合法的认证用户,现在我改用writer用户发送——为此我需要创建一个名为producer.conf的配置文件给producer程序使用,其内容如下:

security.protocol=SASL_PLAINTEXT
sasl.mechanism=SCRAM-SHA-512
sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="writer" password="writer-pwd";

之后运行console-producer脚本:

$ bin/kafka-console-producer.sh --broker-list 172.21.0.9:9092,172.21.0.9:9093 --topic test --producer.config /opt/data/kafka_2.12-2.1.0/producer.conf
>hello
[2019-02-05 18:25:40,272] WARN [Producer clientId=console-producer] Bootstrap broker 172.21.0.9:9092 (id: -1 rack: null) disconnected (org.apache.kafka.clients.NetworkClient)

异常发生变化了,现在报的是“无法创建连接”的错误,这是因为writer用户没有对test topic的写权限所致,故需要给writer用户增加该topic的写权限:

$ bin/kafka-acls.sh --authorizer kafka.security.auth.SimpleAclAuthorizer --authorizer-properties zookeeper.connect=172.21.0.9:2181 --add --allow-principal User:writer --operation Write --topic test
Adding ACLs for resource `Topic:LITERAL:test`:
User:writer has Allow permission for operations: Write from hosts: *

Current ACLs for resource `Topic:LITERAL:test`:
User:writer has Allow permission for operations: Write from hosts: *

再次执行console-producer脚本:

$ bin/kafka-console-producer.sh --broker-list 172.21.0.9:9092,172.21.0.9:9093 --topic test --producer.config /opt/data/kafka_2.12-2.1.0/producer.conf
>hello
>Kafka

发送成功!

下面是配置consumer程序,和producer一样,为reader用户创建consumer.conf,同时设置对topic的读权限:

security.protocol=SASL_PLAINTEXT
sasl.mechanism=SCRAM-SHA-512
sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="reader" password="reader-pwd";

$ bin/kafka-acls.sh --authorizer kafka.security.auth.SimpleAclAuthorizer --authorizer-properties zookeeper.connect=172.21.0.9:2181 --add --allow-principal User:reader --operation Read --topic test
Adding ACLs for resource `Topic:LITERAL:test`:
User:reader has Allow permission for operations: Read from hosts: *

Current ACLs for resource `Topic:LITERAL:test`:
User:writer has Allow permission for operations: Write from hosts: *
User:reader has Allow permission for operations: Read from hosts: *

执行console-consumer脚本:

$ bin/kafka-console-consumer.sh --bootstrap-server 172.21.0.9:9092,172.21.0.9:9093 --topic test --from-beginning --consumer.config /opt/data/kafka2-2.1.0/consumer.conf --group test-group
[2019-02-05 18:55:57,272] ERROR Error processing message, terminating consumer process: (kafka.tools.ConsoleConsumer$)
org.apache.kafka.common.errors.GroupAuthorizationException: Not authorized to access group: test-group

报错提示reader用户没有访问consumer group的权限,加之:

$ bin/kafka-acls.sh --authorizer kafka.security.auth.SimpleAclAuthorizer --authorizer-properties zookeeper.connect=172.21.0.9:2181 --add --allow-principal User:reader --operation Read --group test-group
Adding ACLs for resource `Group:LITERAL:test-group`:
User:reader has Allow permission for operations: Read from hosts: *

Current ACLs for resource `Group:LITERAL:test-group`:
User:reader has Allow permission for operations: Read from hosts: *

再次执行console-consumer脚本:

$ bin/kafka-console-consumer.sh --bootstrap-server 172.21.0.9:9092,172.21.0.9:9093 --topic test --from-beginning --consumer.config /opt/data/kafka_2.12-2.1.0/consumer.conf --group test-group
hello
Kafka

6. 动态增加/删除用户

现在我们在不重启broker的情况下增加新用户writer1和reader1,分别为它们赋予test topic的写权限和读权限:

$ bin/kafka-configs.sh --zookeeper 172.21.0.9:2181 --alter --add-config 'SCRAM-SHA-256=[iterations=8192,password=writer1-pwd],SCRAM-SHA-512=[password=writer1-pwd]' --entity-type users --entity-name writer1
$ bin/kafka-configs.sh --zookeeper 172.21.0.9:2181 --alter --add-config 'SCRAM-SHA-256=[password=reader1-pwd],SCRAM-SHA-512=[password=reader1-pwd]' --entity-type users --entity-name reader1

$ bin/kafka-acls.sh --authorizer kafka.security.auth.SimpleAclAuthorizer --authorizer-properties zookeeper.connect=172.21.0.9:2181 --add --allow-principal User:writer1 --operation Write --topic test

$ bin/kafka-acls.sh --authorizer kafka.security.auth.SimpleAclAuthorizer --authorizer-properties zookeeper.connect=172.21.0.9:2181 --add --allow-principal User:reader1 --operation Read --topic test

$ bin/kafka-acls.sh --authorizer kafka.security.auth.SimpleAclAuthorizer --authorizer-properties zookeeper.connect=172.21.0.9:2181 --add --allow-principal User:reader1 --operation Read --group test-group1

同时删除原来的用户writer:

bin/kafka-configs.sh --zookeeper 172.21.0.9:2181 --alter --delete-config 'SCRAM-SHA-256' --entity-type users --entity-name writer
bin/kafka-configs.sh --zookeeper 172.21.0.9:2181 --alter --delete-config 'SCRAM-SHA-512' --entity-type users --entity-name writer

现在检验writer用户不能写入消息:

$ bin/kafka-console-producer.sh --broker-list 172.21.0.9:9092,172.21.0.9:9093 --topic test --producer.config /opt/data/kafka_2.12-2.1.0/producer.conf
>hello by writer
[2019-02-06 09:30:54,492] ERROR [Producer clientId=console-producer] Connection to node -2 (172.21.0.9/172.21.0.9:9093) failed authentication due to: Authentication failed due to invalid credentials with SASL mechanism SCRAM-SHA-512 (org.apache.kafka.clients.NetworkClient)
[2019-02-06 09:30:54,492] ERROR Error when sending message to topic test with key: null, value: 15 bytes with error: (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
org.apache.kafka.common.errors.SaslAuthenticationException: Authentication failed due to invalid credentials with SASL mechanism SCRAM-SHA-512
[2019-02-06 09:30:54,493] ERROR [Producer clientId=console-producer] Connection to node -1 (172.21.0.9/172.21.0.9:9092) failed authentication due to: Authentication failed due to invalid credentials with SASL mechanism SCRAM-SHA-512 (org.apache.kafka.clients.NetworkClient)

最后修改producer.conf中的writer为writer1,验证writer1用户有权限生产消息:

$ bin/kafka-console-producer.sh --broker-list 172.21.0.9:9092,172.21.0.9:9093 --topic test --producer.config /opt/data/kafka_2.12-2.1.0/producer.conf
>hello by writer1
>successful
>

至此,一个支持动态增加/删除用户的Kafka安全配置就做好了。

Kafka认证权限配置(动态添加用户)的更多相关文章

  1. ASP.NET动态添加用户控件的方法

    本文实例讲述了ASP.NET动态添加用户控件的方法.分享给大家供大家参考.具体实现方法如下: 为了让用户控件能ASP.NET页面实现动态添加,首先写一个接口IGetUCable,这个接口有一个函数,返 ...

  2. SharePoint 2013 表单认证使用ASP.Net配置工具添加用户

    前 言 上面一篇博客,我们了解到如何为SharePoint 2013配置表单身份认证,但是添加用户是一个麻烦事儿:其实,我们还可以用Asp.Net的配置工具,为SharePoint 2013添加表单用 ...

  3. 一个简单的以User权限启动外部应用程序(用NetUserAdd函数和USER_INFO_1结构体动态添加用户,然后用CreateProcessWithLogonW启动程序)

    版权声明:本文为博主原创文章,未经博主允许不得转载. BOOL ExecuteAsUser(LPCWSTR lpszUserName, LPCWSTR lpszPassword, LPCWSTR lp ...

  4. php使用insert语句动态添加用户

    <html> <head> <title>Adding User</title> </head> <body> <h2&g ...

  5. Jenkins配置:添加用户和管理权限

    Jenkins配置:添加用户和管理权限 参考文章:http://www.cnblogs.com/zz0412/p/jenkins_jj_14.html 今天给大家说说使用Jenkins专有用户数据库的 ...

  6. IdentityServer4【QuickStart】之利用OpenID Connect添加用户认证

    利用OpenID Connect添加用户认证 利用OpenID Connect添加用户认证 在这个示例中我们想要通过OpenID Connect协议将交互用户添加到我们的IdentityServer上 ...

  7. nginx 添加用户认证

    nginx 添加用户认证  nginx 配置文件添加: 配置代理添加用户认证:server {   listen       ;   server_name localhost;   location ...

  8. 巨蟒django之权限7:动态生成一级&&二级菜单

    内容回顾: . 权限的控制 . 表结构设计 存权限的信息 用户表 - name 用户名 - pwd 密码 - roles 多对多 角色表 - name - permissions 多对多 权限表 - ...

  9. jenkins权限配置

    1. 授权匿名账户权限 2 注册新用户,并且把匿名权限删除,添加用户权限 Overall(全局) Credentials(凭证) Slave(节点) Job(任务) View(视图) Administ ...

随机推荐

  1. PAT基础6-10

    6-10 阶乘计算升级版 (20 分) 本题要求实现一个打印非负整数阶乘的函数. 函数接口定义: void Print_Factorial ( const int N ); 其中N是用户传入的参数,其 ...

  2. CSS_选择符

    2016-10-28 <CSS入门经典>第五章 以下提示注意事项: 1.如何选择使用id选择符还是class选择符:当确信id选择符在页面的唯一性时,就可以使用id选择符. 2.通用选择符 ...

  3. 团队——League of Programers简介

    团队名称  League of Programers 团队成员简介 武璧泽:编程能力较强,善于程序思路设计: 邹兰兰:擅长代码的分析.编写与调试: 倪彤炜:擅长解决代码的修正与编写,善于调节团队关系: ...

  4. git强制修改注释

    在一些公司项目中,常常要求git注释提交的时候加上前缀,比如JIRA号,但是有的时候我们常常会忘了 如果用source tree等一些工具,会推送到本地仓库一半,但远程又上不去. 这个时候我们就需要强 ...

  5. 微软“小冰”识狗与人工神经网络(V)

    实际上.微软早在2014年7月14日首次透露了一项雄心勃勃的研究计划"亚当计划"("Projrct Adam"),该项目是有关计算机视觉方面的研究项目,也就是后 ...

  6. 【PMP】易混淆知识点

    一.混淆概念 德尔菲技术 德尔菲技术是组织专家达成一致意见的一种方法.项目专家匿名参与其中.组织者使用调查问卷就重要的项目议题征询意见,然后对专家的答卷进行归纳,并把结果反馈给专家做进一步评论.这个过 ...

  7. springcloud灰度发布实现方案

    Nepxion Discovery是一款对Spring Cloud Discovery服务注册发现.Ribbon负载均衡.Feign和RestTemplate调用.Hystrix或者阿里巴巴Senti ...

  8. go test 测试用例那些事

    go test命令,相信大家都不陌生,常见的情况会使用这个命令做单测试.基准测试和http测试.go test还是有很多flag 可以帮助我们做更多的分析,比如测试覆盖率,cpu分析,内存分析,也有很 ...

  9. Navicat http 通道增加验证

    ntunnel_mysql.php 中增加 function check() { if (!isset($_SERVER['PHP_AUTH_USER'])) { header('WWW-Authen ...

  10. 解决Visual Studio调试突然变慢卡死的问题

    最开始摸不到头脑,之前还能好好调试的啊.后来在VS的调试菜单的符号选项里面发现了系统环境变量_NT_SYMBOL_PATH 的值为:srv*c:\symbols*http://msdl.microso ...