1、为什么要开启ACL

通过之前的文章我们已经知道怎么安装RocketMq了。如果你还不会安装RocketMq可以查看我的这篇文章:快速入门一篇搞定RocketMq-实现微服务实战落地 进行软件安装,附文章地址:https://www.cnblogs.com/sowler/p/18173752 。虽说已经安装成功了,但是它现在在服务器上面还处于"裸奔"状态。如果是公司内网服务器还好,有一层安全保障。但是如果是公网服务器黑客可以根据RocketMq端口号入侵服务器系统植入木马病毒,给服务器带来安全漏洞。所以如果部署在公网环境下,强烈建议开启RocketMq的ACL机制以加强系统的安全性。

2、ACL的作用

ACL主要是为了增强系统的安全性和保护消息队列数据的机密性。通过ACL,可以限制用户或应用程序对消息队列的访问权限,只有经过授权的用户才能进行相关操作,如发送消息、消费消息等。防止未经授权的用户或恶意应用程序对消息队列进行操作,减少潜在的安全风险和数据泄露的可能性。同时,ACL还可以帮助管理者更好地控制系统的访问权限,提高系统的可控性和安全性。总体来说,开启ACL是一种有效的安全措施,可以保护RocketMq系统免受未经授权的访问和潜在的安全威胁。

3、ACL是什么

RocketMQ的ACL(Access Control List)是一种安全机制,用于对消息中间件的访问进行授权和限制。ACL机制可以确保只有具备相应权限的用户才能执行特定的操作,从而保护消息系统的安全性。而ACL管理员可以对以下操作进行细粒度的控制和权限管理:

  • Topic级别权限控制: 管理员可以对每个Topic设置读写权限,决定哪些用户或角色有权发送和订阅该主题的消息。
  • Consumer组权限控制: 管理员可以为每个消费者组分配订阅权限,控制哪些用户或角色有权使用该消费者组并接收消息。
  • IP地址访问控制: 管理员可以基于客户端的IP地址进行访问控制,只允许特定的IP地址范围访问消息中间件。

4、服务器开启ACL

首先我们查看RocketMq官网选择4.X版本的文档进行查看,找到控制权限菜单。链接:https://rocketmq.apache.org/zh/docs/4.x/bestPractice/04access

通过说明,我们可以看到权限控制配置文件位置在 /conf/plain_acl.yml ,知道配置文件后进入 conf 目录,首先先备份一份文件防止后面改错了无法恢复,然后在编辑该文件。

#备份文件
cp plain_acl.yml plain_acl.yml.init.bak #编辑文件
vim plain_acl.yml

配置信息如下

#白名单中,不会走acl鉴权
globalWhiteRemoteAddresses:
#- 192.168.0.102 accounts: #用户信息,默认配置了两个用户信息。一个管理员用户,一个普通用户
- accessKey: rocket0001Mq #用户名
secretKey: 1234asdf #密码
whiteRemoteAddress: #192.168.0.102
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: rocketAdminMq #用户名
secretKey: admin1234asdf #密码
whiteRemoteAddress: #192.168.1.*
# if it is admin, it could access all resources
admin: true

通过官网文档我们可以看到配置说明

权限说明:

plain_acl.yml 配置文件中按照上述说明定义好权限属性后,接下来我们需要修改 broker.conf 配置文件开启ACL开关。官网文档上面也给了相关说明,参照官网配置即可。

编辑 vim broker.conf 文件,在文件末尾加入配置 aclEnable=true

#所属集群名字
brokerClusterName=DefaultCluster
#broker名字,集群的时候不同的配置文件填写的不一样,如果在这里使用:broker-a,在另外一个使用:broker-b
brokerName=broker-a #0表示Master,>0表示Slave
brokerId=0 #删除文件时间点,默认凌晨4点
deleteWhen=04 #文件保留时间,默认48小时
fileReservedTime=48 #Broker角色 ASYNC_MASTER 异步复制/SYNC_MASTER 同步双写
brokerRole=ASYNC_MASTER ##刷盘方式 ASYNC_FLUSH 异步刷盘 SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH #nameServer地址,多个,分号分割
namesrvAddr=192.168.42.130:9876 #设置IP 公网Ip
brokerIP1=192.168.42.130 #允许Broker自动创建Topic
autoCreateTopicEnable=true #Broker 对外服务的监听端口
listenPort=10911 #开启ACL安全认证
aclEnable=true

开启后重新启动 Broker 程序。重启成功后,如果中间需要修改 plain_acl.yml 配置文件,修改成功后,不需要重新启动 BrokerStartup 重新了。ACL有自动重载机制,会自动加载已经修改的 plain_acl.yml 配置文件。

5、rocketmq-dashboard 开启认证

通过服务器端开启ACL后,在打开MQ监控中心 rocketmq-dashboard 发现报错了,已经连接不上mq服务器了,这就说明ACL开启成功了。报错信息 No accessKey is configured

[2024-05-17 11:53:30.956]  INFO create MQAdmin instance ClientConfig [namesrvAddr=192.168.42.130:9876, clientIP=192.168.1.4, instanceName=1715918010272, clientCallbackExecutorThreads=8, pollNameServerInterval=30000, heartbeatBrokerInterval=30000, persistConsumerOffsetInterval=5000, pullTimeDelayMillsWhenException=1000, unitMode=false, unitName=null, vipChannelEnabled=false, useTLS=false, language=JAVA, namespace=null] success.
[2024-05-17 11:53:31.149] ERROR Unexpected error occurred in scheduled task
java.lang.RuntimeException: org.apache.rocketmq.client.exception.MQBrokerException: CODE: 1 DESC: org.apache.rocketmq.acl.common.AclException: No accessKey is configured, org.apache.rocketmq.acl.plain.PlainPermissionLoader.validate(PlainPermissionLoader.java:189) BROKER: 192.168.42.130:10911
For more information, please visit the url, http://rocketmq.apache.org/docs/faq/
at com.google.common.base.Throwables.propagate(Throwables.java:241)
at org.apache.rocketmq.dashboard.task.DashboardCollectTask.collectTopic(DashboardCollectTask.java:161)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
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.PlainPermissionLoader.validate(PlainPermissionLoader.java:189) BROKER: 192.168.42.130:10911

所以我们需要通过账号密码来连接mq服务器,在rocketmq-dashboard 的配置文件 application.properties 中添加账号密码信息。

rocketmq.config.accessKey=rocketAdminMq
rocketmq.config.secretKey=admin1234asdf

添加配置成功后重新打包部署到服务器。启动成功再次访问 rocketmq-dashboard

没有报错,启动成功。

6、Java通过认证方式连接

RocketMq开启ACL后,在不配置账号密码情况下,启动项目发送MQ消息的时候也会报错。报错信息如下:

2024-05-18 16:37:54.260 ERROR -[TaskUtils.java:95]- Unexpected error occurred in scheduled task
org.springframework.messaging.MessagingException: Send [3] times, still failed, cost [90]ms, Topic: blog_operation_sow, BrokersSent: [broker-a, broker-a, broker-a]
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:403) BROKER: 192.168.42.130:9876

No accessKey is configured 通过报错信息显示,需要配置账号和密码,所以需要配置ACL的连接信息连接Mq服务器发送消息。配置文件添加信息:

rocketmq: # rocketMQ配置
# name server地址
name-server: 192.168.42.130:9876
producer:
group: message_group
# 发送消息超时时间,默认3000
sendMessageTimeout: 10000
# 发送消息失败重试次数,默认2
retryTimesWhenSendFailed: 2
# 异步消息重试此处,默认2
retryTimesWhenSendAsyncFailed: 2
# 消息最大长度,默认1024 * 1024 * 4(默认4M)
maxMessageSize: 4096
# 压缩消息阈值,默认4k(1024 * 4)
compressMessageBodyThreshold: 4096
# 是否在内部发送失败时重试另一个broker,默认false
retryNextServer: false
access-key: rocketAdminMq # 拥有改 ‘message_group’组发送权限的用户信息
secret-key: admin1234asdf # 密码
consumer:
pull-batch-size: 10
group: message_group
access-key: rocketAdminMq # 拥有改‘message_group’组消费权限的用户信息
secret-key: admin1234asdf # 密码

配置成功后,测试消息发送信息:

// 定时向Mq发送数据
@Component
public class RocketStorage { @Autowired
private RocketMQTemplate rocketMQTemplate; @Scheduled(fixedDelay = 1000L * 60,initialDelay = 1000L * 20)
public void store() {
//String message = String.format("%s,%s,%s",value,type,timestamp);
System.out.println("aaaaaa");
rocketMQTemplate.convertAndSend("blog_operation_sow","aaaaaaaaa");
} }

消费者监听接收数据:

@RocketMQMessageListener(consumerGroup = "message_group",topic = "blog_operation_sow")
public class RocketDataConsumer implements RocketMQListener { @Autowired
@Qualifier("dataPersist")
private IDataPersist dataPersist; @Override
public void onMessage(Object o) {
log.info("Operation RocketMq 接收到的信息 . . . . . .:{}",o);
dataPersist.put(o.toString(),1,System.currentTimeMillis());
}
}

启动项目查看控制台信息,可以看到数据发送和接收成功。

7、Java开启认证踩坑说明

7.1 问题记录

在配置文件加入 access-keysecret-key 后,刚开始一直报 AclException: No accessKey is configured 错误,但是配置文件中已经配置账号密码信息了。不知道为什么没有生效。后来看了一下引入的Maven依赖版本为:

        <!--RocketMQ-->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.2.1</version>
</dependency>

通过IDEA查看依赖jar包发现引入的RocketMq依赖版本高了。

通过上图可以看到,我们引入的客户端版本是4.9.1版本,但是服务器目前部署的版本是4.4.0。然后以为是maven依赖引入的版本太高了,就把rocketMq依赖降到了4.4.0版本。maven依赖如下:

        <dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.0.2</version>
</dependency>

再次通过IDEA查看客户端依赖,发现版本已经改为4.4.0了

修改maven依赖成功后,再次启动项目。以为这次会启动成功,但是还是启动失败了。版本问题已经解决了,就不是版本问题了。后来看了下相关问题说明。发现RocketMq是在4.4.0版本才开始有ACl认证的,可能是这个版本客户端不支持通过yaml 配置文件配置ACl的账号密码信息。需要手动进行编写Java配置文件进行发送消息。然后我就直接放弃了这种方法,直接升级服务器RocketMq版本从4.4.0升级为4.9.1。

7.2 升级版本

既然决定升级服务器RocketMq版本信息了,那就开干。有了之前的安装经验,这次也很好安装。首先在官网下载RocketMq的4.9.1版本。地址:https://rocketmq.apache.org/download 下载成功后上传服务器到rocketMq目录下。

进入rocktmq-4.9.1目录,按照之前的步骤进行操作即可。先修改启动脚本,先备份在修改。进入 bin 目录下开始备份。

cp runserver.sh runserver.sh.init.bak 

cp runbroker.sh runbroker.sh.init.bak

修改JVM参数即可。备份成功后,然后在进入 conf 目录,修改配置文件信息并开启ACL配置,如何开启ACL和上面操作一致。我们也可以备份一下 broker.confplain_acl.yml 文件,把在rocketmq-4.4.0目录里面的配置信息直接拷贝到 rocketmq-4.9.1目录下面。拷贝成功后,给需要给配置文件授可执行权限。

chmod +x broker.conf plain_acl.yml

接下来就可以启动rocketmq了,按照之前方式启动即可。先启动 namesrv 在启动 broker

nohup sh bin/mqnamesrv -n 192.168.42.130:9876 > /dev/null 2>&1 &  

nohup sh bin/mqbroker -n 192.168.42.130:9876 -c conf/broker.conf autoCreateTopicEnable=true >/dev/null 2>&1 &

启动成功后,版本就升级成功了。由于rocketmq默认采用持久化存储,当使用持久化存储模式时,消息会被写入磁盘,并存储在指定的存储路径下。默认情况下,存储路径为$HOME/store也可以通过配置文件进行修改。在存储路径下,RocketMQ会根据一些规则和目录结构来组织消息存储文件。其中,消息数据文件commitlog存储在$HOME/store/commitlog目录下,而消费进度文件 consumequeue 存储在$HOME/store/consumequeue目录下。由于有持久化存储,所以原来的数据也不会丢失。

7.3 查看监控

由于RocketMq的配置文件还是采用之前的,所以不需要改动 rocketmq-dashboard 可以直接访问地址。查看集群信息:

从上图version 版本可以看出当前版本为 4.9.1 说明已经连接升级成功了。可以查看监控数据:

至此,RockeMq服务器版本升级完毕。

8、总结

通过以上方式,RocketMq安全措施就配置成功了。这是我自己在使用RocketMq的搭建过程,分享出来让大家少走弯路,中间也许会有一些地方考虑不周,欢迎各位指点。感谢大家阅读。

公众号文章链接:https://mp.weixin.qq.com/s/XTB9rrtpAh5q9QI6LkqSEw 如果文章对你有所帮助,欢迎大家点个推荐和关注。

RocketMq开启安全认证ACL-解决服务器系统安全漏洞的更多相关文章

  1. MySQL开启SSL认证,以及简单优化

    1.1 MySQL开启SSL认证 #生成一个 CA 私钥 [root@db01 ssl]# openssl genrsa 2048 > ca-key.pem Generating RSA pri ...

  2. MongDB开启权限认证

    在生产环境中MongoDB已经使用有一段时间了,但对于MongoDB的数据存储一直没有使用到权限访问(MongoDB默认设置为无权限访问限制),最近在酷壳网看了一篇技术文章(https://cools ...

  3. Nginx 基于客户端 IP 来开启/关闭认证

    前些日子帮助公司在搭建了一个内部资源的导航页面,方便公司员工访问各种常用的系统.因为这个页面包含一些敏感信息,我们希望对其做认证,但仅当从外网访问的时候才开启,当从公司内网访问的时候,则无需输入账号密 ...

  4. mongodb分片集群开启安全认证

    原文地址:https://blog.csdn.net/uncle_david/article/details/78713551 对于搭建好的mongodb副本集加分片集群,为了安全,启动安全认证,使用 ...

  5. mongodb集群搭建(分片+副本)开启安全认证

    关于安全认证得总结: 这个讲述的步骤也是先创建超管用户,关闭服务,然后生成密钥文件,开启安全认证,启动服务 相关概念 先来看一张图: 从图中可以看到有四个组件:mongos.config server ...

  6. 解决服务器复制中SID冲突问题

    解决服务器复制中SID冲突问题 如果你有多部的主机需要安装,最快的方法是什么?想必就是用像GHOST之类的软件来进行硬盘的复制.当然,如果是安装在虚拟机之中,则需要复制虚拟的硬盘档案即可,以微软的VP ...

  7. 如何为企业选择最理想的Linux服务器系统?

    [2013年10月12日 51CTO外电头条]什么样的Linux服务器最合适您的企业?简言之,它需要为员工带来工作所需的理想支持效果. 相对于成百上千种Linux桌面系统,Linux服务器系统的数量其 ...

  8. Windows Server 2008 R2服务器系统安全设置参考指南

    Server 2008 R2服务器系统安全设置参考指南  重点比较重要的几部 1.更改默认administrator用户名,复杂密码 2.开启防火墙 3.安装杀毒软件 1)新做系统一定要先打上补丁(升 ...

  9. ios开启双重认证之填坑式教学

    2019.03.01.阳光明媚(不,,,有些雾霾..) 本来打算发布一个新版本app,修复一些小小bug, 然而,打包出错了,,错误是显示账号无连接.. 顿时慌出了天际,,以为是账号的证书问题,,最烦 ...

  10. linux服务器系统负载监控-shell脚本

    一.监控服务器系统负载情况: 1.用uptime命令查看当前负载情况(1分钟,5分钟,15分钟平均负载情况) # uptime   15:43:59 up 186 days, 20:04,  1 us ...

随机推荐

  1. C# 运算符详解:包含算术、赋值、比较、逻辑运算符及 Math 类应用

    运算符用于对变量和值执行操作.在C#中,有多种运算符可用,包括算术运算符.关系运算符.逻辑运算符等. 算术运算符 算术运算符用于执行常见的数学运算: int x = 100 + 50; // 加法,结 ...

  2. SQL 中的运算符与别名:使用示例和语法详解

    SQL中的IN运算符 IN运算符允许您在WHERE子句中指定多个值,它是多个OR条件的简写. 示例:获取您自己的SQL Server 返回所有来自'Germany'.'France'或'UK'的客户: ...

  3. C++调用Python-5:调用Python函数,传参数字+字符串

    # mytest.py def myjoin(a, b): print("num a + str b") return f"{a}=={b}" #include ...

  4. 实验1 c语言开发环境使用和数据类型 运算符 表达式

    #include<stdio.h> #include<stdlib.h> int main() { printf(" O\n"); printf(" ...

  5. Launching Teamviewer remotely through SSH

    Launching Teamviewer remotely through SSH When you need to manage your Server remotely, but you can ...

  6. mysql 必知必会整理—游标[十四]

    前言 简单介绍一下游标. 正文 需要MySQL 5 MySQL 5添加了对游标的支持,因此,本章内容适用于MySQL 5及以后的版本. 有时,需要在检索出来的行中前进或后退一行或多行.这就是使用游标的 ...

  7. redis+lua脚本实现接口限流

    写在前面 在多线程的情况下对一个接口进行访问,如果访问次数过大,且没有缓存存在的情况下大量的请求打到数据库可能会存在数据库宕机,从而造成服务的不可用性.往往我们需要对其进行限流操作用来保证服务的高可用 ...

  8. Django框架——路由分发、名称空间、虚拟环境、视图层三板斧、JsonResponse对象、request获取文件、FBV与CBV、CBV源码剖析、模版层

    路由分发 # Django支持每个应用都可以有自己独立的路由层.静态文件.模版层.基于该特性多人开发项目就可以完全解耦合,之后利用路由分发还可以整合到一起 多个应用都有很多路由与视图函数的对应关系 这 ...

  9. Oracle常用的创建表语句

    Oracle常用的创建表语句 Oracle常用的创建表语句 指定字段的创建 --指定字段的创建 create table table_name( test_1(字段名1) varchar2(50),( ...

  10. 力扣38(java)-外观数列(中等)

    题目: 给定一个正整数 n ,输出外观数列的第 n 项. 「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述. 你可以将其视作是由递归公式定义的数字字符串序列: count ...