一、前言
在上篇文章 docker-compose 搭建RocketMQ 5.1.0 集群(双主双从模式) | Spring Cloud 28 中对于RocketMQ 5.1.0
集群的搭建进行完整的介绍,本章结合上章内容对于开启权限控制(ACL
)和使用中的注意事项进行介绍。
更多官方介绍:https://github.com/apache/rocketmq/tree/master/docs/cn
二、权限控制特性介绍
权限控制(ACL
)主要为RocketMQ
提供Topic
资源级别的用户访问控制。
用户在使用RocketMQ
权限控制时,可以在Client
客户端通过 RPCHook
注入AccessKey
和SecretKey签名
;同时,将对应的权限控制属性(包括:Topic访问权限
、IP白名单
和AccessKey
和SecretKey签名
等)设置在distribution/conf/plain_acl.yml
的配置文件中。
Broker
端对AccessKey
所拥有的权限进行校验,校验不过,抛出异常.
ACL
客户端可以参考:org.apache.rocketmq.example.simple
包下面的AclClient代码。
三、权限控制的定义与属性值
3.1权限定义
对RocketMQ
的Topic
资源访问权限控制定义主要如下表所示,分为以下四种:
权限 | 含义 |
---|---|
DENY | 拒绝 |
ANY | PUB 或者 SUB 权限 |
PUB | 发送权限 |
SUB | 订阅权限 |
3.2 权限定义的关键属性
字段 | 取值 | 含义 |
---|---|---|
globalWhiteRemoteAddresses | *;192.168.*.*;192.168.0.1 | 全局IP白名单 |
accessKey | 字符串 | Access Key |
secretKey | 字符串 | Secret Key |
whiteRemoteAddress | *;192.168.*.*;192.168.0.1 | 用户IP白名单 |
admin | true;false | 是否管理员账户 |
defaultTopicPerm | DENY;PUB;SUB;PUB|SUB | 默认的Topic权限 |
defaultGroupPerm | DENY;PUB;SUB;PUB|SUB | 默认的ConsumerGroup权限 |
topicPerms | topic=权限 | 各个Topic的权限 |
groupPerms | group=权限 | 各个ConsumerGroup的权限 |
四、权限控制主要流程
ACL
主要流程分为两部分,主要包括:权限解析和权限校验。
4.1 权限解析
Broker
端对客户端的RequestCommand
请求进行解析,拿到需要鉴权的属性字段。
主要包括:
AccessKey
:类似于用户名,代指用户主体,权限数据与之对应;Signature
:客户根据 SecretKey
签名得到的串,服务端再用SecretKey
进行签名验证; 4.2 权限校验
Broker
端对权限的校验逻辑主要分为以下几步:
(1)检查是否命中全局 IP 白名单
;如果是,则认为校验通过;否则走 2;
(2)检查是否命中用户 IP 白名单
;如果是,则认为校验通过;否则走 3;
(3)校验签名
,校验不通过,抛出异常;校验通过,则走 4;
(4)对用户请求所需的权限
和 用户所拥有的权限
进行校验;不通过,抛出异常;
用户所需权限的校验需要注意已下内容:
(1)特殊的请求例如 UPDATE_AND_CREATE_TOPIC
等,只能由 admin
账户进行操作;
(2)对于某个资源,如果有显性配置权限,则采用配置的权限;如果没有显性配置权限,则采用默认的权限;
五、热加载修改后权限控制定义
RocketMQ
的权限控制存储的默认实现是基于yml
配置文件。用户可以动态修改权限控制定义的属性,而不需重新启动Broker
服务节点。
六、权限控制的使用限制
(1)如果ACL
与高可用部署(Master/Slave
架构)同时启用,那么需要在Broker Master
节点的distribution/conf/plain_acl.yml
配置文件中需设置全局白名单信息,即为将Slave
节点的ip
地址设置至Master
节点plain_acl.yml
配置文件的全局白名单中。
(2)如果ACL
与高可用部署(多副本Dledger
架构)同时启用,由于出现节点宕机时,Dledger Group
组内会自动选主,那么就需要将Dledger Group
组内所有Broker
节点的plain_acl.yml
配置文件的白名单设置所有Broker
节点的ip
地址。
七、开启集群权限控制
根据上章上述的内容介绍,结合上篇文章 docker-compose 搭建RocketMQ 5.1.0 集群(双主双从模式) | Spring Cloud 28 对集群中所有的Broker
端开启ACL
特性:
7.1 192.168.0.31配置改造
对192.168.0.31
的文件:
broker-a.propertiesbroker-b-s.properties
追加以下内容:
# 权限控制aclEnable=true
开启ACL
特性。
7.2 192.168.0.31配置改造
对192.168.0.41
的文件:
broker-b.propertiesbroker-a-s.properties
追加以下内容:
# 权限控制aclEnable=true
开启ACL
特性。
7.3 编辑plain_acl.yml
配置文件plain_acl.yml
中定义权限属性:
# 设置全局白名单信息globalWhiteRemoteAddresses: - 192.168.0.* - 172.30.1.* accounts: - accessKey: RocketMQ secretKey: 12345678 whiteRemoteAddress: admin: false defaultTopicPerm: DENY defaultGroupPerm: SUB topicPerms: - topicA=DENY - topicB=PUB|SUB - topicC=SUB groupPerms: # the group should convert to retry topic - groupA=DENY - groupB=PUB|SUB - groupC=SUB - accessKey: RocketMQAdmin secretKey: 1qaz@WSX whiteRemoteAddress: # if it is admin, it could access all resources admin: true
需要自行将此plain_acl.yml
分发至192.168.0.31
和 192.168.0.41
集群中所有的Broker
端。
针对RocketMQ 5.1.0
版本的accessKey
属性长度需大于6
因部署的rocketmq-dashboard
与集群中所有的Broker
端在同一网段内,故配置globalWhiteRemoteAddresses
属性为IP段
后无需对rocketmq-dashboard
进行修改,否则需对rocketmq-dashboard
添加accessKey
和secretKey
属性。对应修改方法可见配置文件:application.yml
或可通过以下设置容器环境变量方式实现:
environment: JAVA_OPTS: -Drocketmq.namesrv.addr=rmqnamesrv:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false -Drocketmq.config.accessKey=RocketMQAdmin -Drocketmq.config.secretKey=1qaz@WSX
更多关于rocketmq-dashboard
的使用请见:
https://github.com/apache/rocketmq-dashboard/blob/master/docs/1_0_0/UserGuide_CN.md
更多关于Spring Boot
集成RocketMQ
开启ACL
的使用示例请见:https://github.com/apache/rocketmq-spring/tree/master/rocketmq-spring-boot-samples
更多官网ACL
的Java
客户端使用示例请见:
https://github.com/apache/rocketmq/blob/release-5.1.0/example/src/main/java/org/apache/rocketmq/example/benchmark/AclClient.java
八、Java访问开启ACL集群
未进行ACL
配置的Java
客户端访问已开启ACL
集群的集群出现以下异常:
Exception in thread "main" org.apache.rocketmq.client.exception.MQClientException: Send [3] times, still failed, cost [140]ms, Topic: TopicTest, BrokersSent: [broker-a, broker-a, broker-a]See http://rocketmq.apache.org/docs/faq/ for further details.at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:688)at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1398)at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1342)at org.apache.rocketmq.client.producer.DefaultMQProducer.send(DefaultMQProducer.java:330)at com.gm.demo.rocketmq.test1.SyncProducer.main(SyncProducer.java:23)Caused by: org.apache.rocketmq.client.exception.MQBrokerException: CODE: 1 DESC: org.apache.rocketmq.acl.common.AclException: No accessKey is configured, org.apache.rocketmq.acl.plain.PlainPermissionManager.validate(PlainPermissionManager.java:614) BROKER: 192.168.0.31:10911For more information, please visit the url, http://rocketmq.apache.org/docs/faq/at org.apache.rocketmq.client.impl.MQClientAPIImpl.processSendResponse(MQClientAPIImpl.java:666)at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessageSync(MQClientAPIImpl.java:505)at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage(MQClientAPIImpl.java:487)at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage(MQClientAPIImpl.java:431)at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendKernelImpl(DefaultMQProducerImpl.java:877)at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:607)... 4 more
九、ACL mqadmin配置管理
此部分请见官网介绍:https://github.com/apache/rocketmq/blob/master/docs/cn/acl/user_guide.md