RocketMQ ACL 使用指南

一 、什么是 ACL?

ACL 是 access control list 的简称,俗称访问控制列表。访问控制,基本上会涉及
到用户、资源、权限、角色等概念,那在 RocketMQ 中上述会对应哪些对象呢?

  • 用户
    用户是访问控制的基础要素,也不难理解,RocketMQ ACL 必然也会引入用户的概
    念,即支持用户名、密码。
  • 资源
    资源,需要保护的对象,在 RocketMQ 中,消息发送涉及的 Topic、消息消费涉及的
    消费组,应该进行保护,故可以抽象成资源。
  • 权限
    针对资源,能进行的操作,
  • 角色
    RocketMQ 中,只定义两种角色:是否是管理员。
    另外,RocketMQ 还支持按照客户端 IP 进行白名单设置。

二 、 ACL 基本流程图

在讲解如何使用 ACL 之前,我们先简单看一下 RocketMQ ACL 的请求流程:


image.png

对于上述具体的实现,将在后续文章中重点讲解,本文的目的只是希望给读者一个大概
的了解。

三 、如何配置 ACL

1 acl 配置文件

acl 默认的配置文件名:plain_acl.yml,需要放在${ROCKETMQ_HOME}/store/co
nfig 目录下。下面对其配置项一一介绍。
globalWhiteRemoteAddresses
全局白名单,其类型为数组,即支持多个配置。其支持的配置格式如下:


  • 表示不设置白名单,该条规则默认返回 false。

. *

表示全部匹配,该条规则直接返回 true,将会阻断其他规则的判断,请慎重使用。

  • 192.168.0.{100,101}
    多地址配置模式,ip 地址的最后一组,使用{},大括号中多个 ip 地址,用英文逗号(,)隔开。
  • 192.168.1.100,192.168.2.100
    直接使用,分隔,配置多个 ip 地址。
  • 192.168..或 192.168.100-200.10-20
    每个 IP 段使用*或-表示范围。
  • accounts
    配置用户信息,该类型为数组类型。拥有 accessKey、secretKey、whiteRemote
    Address、admin、defaultTopicPerm、defaultGroupPerm、topicPerms、groupPe
    rms 子元素。
  • accessKey
    登录用户名,长度必须大于 6 个字符。
  • secretKey
    登录密码。长度必须大于 6 个字符。
  • whiteRemoteAddress
    用户级别的 IP 地址白名单。其类型为一个字符串,其配置规则与 globalWhiteRemot
    eAddresses,但只能配置一条规则。
  • admin
    boolean 类型,设置是否是 admin。如下权限只有 admin=true 时才有权限执行。
  • UPDATE_AND_CREATE_TOPIC
    更新或创建主题。
  • UPDATE_BROKER_CONFIG
    更新 Broker 配置。
  • DELETE_TOPIC_IN_BROKER
    删除主题。
  • UPDATE_AND_CREATE_SUBSCRIPTIONGROUP
    更新或创建订阅组信息。
  • DELETE_SUBSCRIPTIONGROUP
    删除订阅组信息。
  • defaultTopicPerm
    默认 topic 权限。该值默认为 DENY(拒绝)。
  • defaultGroupPerm
    默认消费组权限,该值默认为 DENY(拒绝),建议值为 SUB。
  • topicPerms
    设置 topic 的权限。其类型为数组,其可选择值在下节介绍。
  • groupPerms
    设置消费组的权限。其类型为数组,其可选择值在下节介绍。可以为每一消费组配置不一样的权限。
  1. RocketMQ ACL 权限可选值
  • DENY
    拒绝。

  • PUB
    拥有发送权限。

  • SUB
    拥有订阅权限。

3. 权限验证流程

上面定义了全局白名单、用户级别的白名单,用户级别的权限,为了更好的配置 ACL
权限规则,下面给出权限匹配逻辑。

image.png

image.png

image.png

四 、使用示例

1. Broker 端安装

首先,需要在 broker.conf 文件中,增加参数 aclEnable=true。并拷贝 distribution/
conf/plain_acl.yml 文件到${ROCKETMQ_HOME}/conf 目录。
broker.conf 的配置文件如下:

brokerClusterName = DefaultCluster
brokerName = broker-b
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
listenPort=10915
storePathRootDir=E:/SH2019/tmp/rocketmq_home/rocketmq4.5MB/store
storePathCommitLog=E:/SH2019/tmp/rocketmq_home/rocketmq4.5MB/store/commitlog
namesrvAddr=127.0.0.1:9876
autoCreateTopicEnable=false
aclEnable=true

plain_acl.yml 文件内容如下:

globalWhiteRemoteAddresses:
accounts:
- accessKey: RocketMQ
secretKey: 12345678
whiteRemoteAddress:
admin: false
defaultTopicPerm: DENY
defaultGroupPerm: SUB
topicPerms:
- TopicTest=PUB
groupPerms:
# the group should convert to retry topic
- please_rename_unique_group_name_4=DENY
- accessKey: admin
secretKey: 12345678
whiteRemoteAddress:
# if it is admin, it could access all resources
admin: true

从上面的配置可知,用户 RocketMQ 只能发送 TopicTest 的消息,其他 topic 无权限发送;拒绝 please_rename_unique_group_name_4 消费组的消息消费,其他消费
组默认可消费。

2 消息发送端示例

public class AclProducer {
    public static void main(String[] args) throws MQClientException, InterruptedException {
        DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name", getAclRPCHook());
        producer.setNamesrvAddr("127.0.0.1:9876");
        producer.start();
        for (int i = 0; i < 1; i++) {
            try {
                Message msg = new Message("TopicTest3" ,"TagA" , ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET));
                SendResult sendResult = producer.send(msg);
                System.out.printf("%s%n", sendResult);
            } catch (Exception e) {
                e.printStackTrace();
                Thread.sleep(1000);
            }
         }
         producer.shutdown();
     }

    static RPCHook getAclRPCHook() {
        return new AclClientRPCHook(new SessionCredentials("rocketmq","12345678"));
    }
}

运行效果如图所示:


image.png

3. 消息消费端示例

public class AclConsumer {
    public static void main(String[] args) throws InterruptedException, MQClientException {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("please_rename_unique_group_name_4", getAclRPCHook(),new AllocateMessageQueueAveragely());
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
        consumer.subscribe("TopicTest", "*");
        consumer.setNamesrvAddr("127.0.0.1:9876");
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List msgs,ConsumeConcurrentlyContext context) {
                System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msgs);
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        }
    }

发现并不没有消息被消费,符合预期。

本文来自『中间件兴趣圈』公众号,仅作技术交流,未授权任何商业行为。

你可能感兴趣的:(RocketMQ ACL 使用指南)