千家信息网

RabbitMQ如何开启SSL与SpringBoot连接测试

发表于:2024-11-11 作者:千家信息网编辑
千家信息网最后更新 2024年11月11日,本文小编为大家详细介绍"RabbitMQ如何开启SSL与SpringBoot连接测试",内容详细,步骤清晰,细节处理妥当,希望这篇"RabbitMQ如何开启SSL与SpringBoot连接测试"文章能
千家信息网最后更新 2024年11月11日RabbitMQ如何开启SSL与SpringBoot连接测试

本文小编为大家详细介绍"RabbitMQ如何开启SSL与SpringBoot连接测试",内容详细,步骤清晰,细节处理妥当,希望这篇"RabbitMQ如何开启SSL与SpringBoot连接测试"文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

楔子

近期公司程序被安全扫描出 远程主机允许明文身份验证 中风险漏洞,查了下修复方案,RabbitMQ官方提供了SSL连接方式,而且 SpringBoot AMQP 也支持 SSL 连接。以下将配置RabbitMQ开启SSL 并使用 SpringBoot Demo 测试连接。

配置 RabbitMQ 开启 SSL

本文基于 CentOS 7 + Git + OpenSSL + yum 安装的 RabbitMQ,需要读者提交安装好。其他方式也可变通参考本文。

生成证书

#克隆生成证书的仓库到当前目录git clone --depth 1 https://github.com/Berico-Technologies/CMF-AMQP-Configuration.gitcd CMF-AMQP-Configuration/ssl#生成ca证书,"MyRabbitMQCA"为自定义名称,名称任意。在当前目录下生成ca目录sh setup_ca.sh MyRabbitMQCA#生成服务端证书,第一个参数是服务端证书前缀,第二个参数是密码。密码任意,在当前目录下生成server目录sh make_server_cert.sh rabbitmq-server 123456#生成客户端证书,第一个参数是客户端证书前缀,第二个参数是密码。密码任意,在当前目录下生成client目录sh create_client_cert.sh rabbitmq-client 654321

配置 RabbitMQ 服务端的证书如下:

ca/cacert.pem #CA证书server/rabbitmq-server.cert.pem #服务端公钥server/rabbitmq-server.key.pem  #服务端私钥

使用 RabbitMQ 服务端公钥证书生成 JKS 证书

# -alias后为别称,-file后是服务端公钥位置,-keystore后是输出JSK证书位置,此处相对路径keytool -import -alias rabbitmq-server \  -file server/rabbitmq-server.cert.pem \  -keystore rabbitmqTrustStore -storepass changeit#输入y回车

配置 RabbitMQ 客户端的证书如下:

client/rabbitmq-client.keycert.p12 #PKCS12证书,包含客户端所需公私钥及中间证书rabbitmqTrustStore #服务端JKS格式公钥

默认 RabbitMQ 配置目录在 /etc/rabbitmq,我们创建个证书目录存放服务端证书

mkdir -p /etc/rabbitmq/ssl#复制服务端必要证书cp ca/cacert.pem \server/rabbitmq-server.cert.pem \server/rabbitmq-server.key.pem /etc/rabbitmq/ssl/

修改 RabbitMQ 配置文件

修改 RabbitMQ 配置文件 /etc/rabbitmq/rabbitmq.config,此文件默认不存在,需要手动创建

[{rabbit, [
{ssl_listeners, [5671]},
{ssl_options, [
{cacertfile, "/etc/rabbitmq/ssl/cacert.pem"},
{certfile, "/etc/rabbitmq/ssl/rabbitmq-server.cert.pem"},
{keyfile, "/etc/rabbitmq/ssl/rabbitmq-server.key.pem"},
{verify, verify_peer},
{fail_if_no_peer_cert, true},
{ciphers, [
"ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-RSA-AES256-GCM-SHA384",
"ECDHE-ECDSA-AES256-SHA384","ECDHE-RSA-AES256-SHA384",
"ECDHE-ECDSA-DES-CBC3-SHA","ECDH-ECDSA-AES256-GCM-SHA384",
"ECDH-RSA-AES256-GCM-SHA384","ECDH-ECDSA-AES256-SHA384",
"ECDH-RSA-AES256-SHA384","DHE-DSS-AES256-GCM-SHA384",
"DHE-DSS-AES256-SHA256","AES256-GCM-SHA384",
"AES256-SHA256","ECDHE-ECDSA-AES128-GCM-SHA256",
"ECDHE-RSA-AES128-GCM-SHA256","ECDHE-ECDSA-AES128-SHA256",
"ECDHE-RSA-AES128-SHA256","ECDH-ECDSA-AES128-GCM-SHA256",
"ECDH-RSA-AES128-GCM-SHA256","ECDH-ECDSA-AES128-SHA256",
"ECDH-RSA-AES128-SHA256","DHE-DSS-AES128-GCM-SHA256",
"DHE-DSS-AES128-SHA256","AES128-GCM-SHA256",
"AES128-SHA256","ECDHE-ECDSA-AES256-SHA",
"ECDHE-RSA-AES256-SHA","DHE-DSS-AES256-SHA",
"ECDH-ECDSA-AES256-SHA","ECDH-RSA-AES256-SHA",
"AES256-SHA","ECDHE-ECDSA-AES128-SHA",
"ECDHE-RSA-AES128-SHA","DHE-DSS-AES128-SHA",
"ECDH-ECDSA-AES128-SHA","ECDH-RSA-AES128-SHA","AES128-SHA"
]}
]}
]}].

主要配置项说明:

  • ssl_listeners 指定 SSL协议的端口号,官方文档 5671

  • ssl_options SSL 认证配置项

  • cacertfile CA 证书位置

  • certfile 公钥证书位置

  • keyfile 密钥证书位置

  • verify

  • verify_peer 客户端与服务端互相发送证书

  • verify_none 禁用证书交换与校验

  • fail_if_no_peer_cert

  • true 不接受没证书的客户端连接

  • false 接受没证书的客户端连接

  • ciphers 加密器(这个翻译不知道算不算对?)

重启 RabbitMQ

#关闭rabbitmqctl stop#启动rabbitmq-server -detached

验证开启 SSL 是否成功

使用 Rabbitmq 自带的诊断工具查看端口监听状态及使用协议

#查看监听rabbitmq-diagnostics listeners#查看支持的TLS版本rabbitmq-diagnostics --silent tls_versions

使用 OpenSSL CLI 工具验证证书是否有效

cd 生成证书的ssl目录#使用客户端证书+CA证书连接RabbitMQ验证。本处MQ与生成证书是同一主机,其他情况请自行考虑。openssl s_client -connect localhost:5671 \  -cert client/rabbitmq-client.cert.pem \  -key client/rabbitmq-client.key.pem \  -CAfile ca/cacert.pem

除了命令行查看外,还可以通过管理界面查看,不过只能确定开启了 SSL 监听,无法确认证书是否通过验证。

编写 SpringBoot 代码连接测试

代码结构

只是使用 start.spring.io 生成的 Maven 工程,依赖了 WEB 和 AMQP

代码及配置

pom.xml

        4.0.0                        org.springframework.boot                spring-boot-starter-parent                2.5.8                                 com.example        demo        0.0.1-SNAPSHOT        demo        Demo project for Spring Boot                        1.8                                                        org.springframework.boot                        spring-boot-starter-amqp                                                        org.springframework.boot                        spring-boot-starter-web                                                        org.springframework.boot                        spring-boot-starter-test                        test                                                        org.springframework.amqp                        spring-rabbit-test                        test                                                                                                        org.springframework.boot                                spring-boot-maven-plugin                                                

启动类 DemoApplication.java

package com.hellxz.rabbitmq.ssl;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class DemoApplication {    public static void main(String[] args) {        SpringApplication.run(DemoApplication.class, args);    }}

RabbitMQ客户端配置类 RabbitFanoutExchangeConfig.java

package com.hellxz.rabbitmq.ssl;import org.springframework.amqp.core.Binding;import org.springframework.amqp.core.BindingBuilder;import org.springframework.amqp.core.FanoutExchange;import org.springframework.amqp.core.Queue;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class RabbitFanoutExchangeConfig {    public static final String FANOUT_EXCHANGE = "fanout.exchange";    public static final String FANOUT_QUEUE1 = "fanout.queue1";    @Bean(name = FANOUT_EXCHANGE)    public FanoutExchange fanoutExchange() {        return new FanoutExchange(FANOUT_EXCHANGE, true, false);    }    @Bean(name = FANOUT_QUEUE1)    public Queue fanoutQueue1() {        return new Queue(FANOUT_QUEUE1, true, false, false);    }        @Bean    public Binding bindingSimpleQueue1(@Qualifier(FANOUT_QUEUE1) Queue fanoutQueue1,                                       @Qualifier(FANOUT_EXCHANGE) FanoutExchange fanoutExchange) {        return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);    }}

发消息测试类 TestController.java

package com.hellxz.rabbitmq.ssl;import org.springframework.amqp.core.Message;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class TestController {    @Autowired    RabbitMQSenderService rabbitMQSenderService;        @GetMapping("/test")    public void sendMsg() {        Message msg = new Message("hello world".getBytes());        try {            rabbitMQSenderService.send(RabbitFanoutExchangeConfig.FANOUT_EXCHANGE,                    RabbitFanoutExchangeConfig.FANOUT_QUEUE1, msg);        } catch (Exception e) {            e.printStackTrace();        }    }}

发消息服务 RabbitMQSenderService.java

package com.hellxz.rabbitmq.ssl;import java.util.UUID;import org.springframework.amqp.core.Message;import org.springframework.amqp.rabbit.connection.CorrelationData;import org.springframework.amqp.rabbit.core.RabbitTemplate;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;@Componentpublic class RabbitMQSenderService {    @Autowired    private RabbitTemplate rabbitTemplate;    public void send(String exchange, String routingkey, Message message) {        CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());        System.out.println("start send msg : " + message);        rabbitTemplate.convertAndSend(exchange, routingkey, message, correlationId);        System.out.println("end send msg : " + message);    }}

消息接收者 RabbitMQReciver.java

package com.hellxz.rabbitmq.ssl;import org.springframework.amqp.rabbit.annotation.RabbitListener;import org.springframework.stereotype.Component;@Componentclass RabbitMQReciver {    @RabbitListener(queues = RabbitFanoutExchangeConfig.FANOUT_QUEUE1)    public void reciveLogAll(String msg) throws Exception {        System.out.println("received msg:" + msg);    }}

配置文件 application.properties

server.port=8085#基础配置请根据实际配置spring.rabbitmq.host=192.168.56.104#ssl协议端口spring.rabbitmq.port=5671spring.rabbitmq.username=adminspring.rabbitmq.password=123456spring.rabbitmq.virtual-host=/#启用rabbitmq客户端SSL连接spring.rabbitmq.ssl.enabled=true#客户端PKCS12证书及密码spring.rabbitmq.ssl.key-store=classpath:ssl/rabbitmq-client.keycert.p12spring.rabbitmq.ssl.key-store-password=654321#公钥证书及类型spring.rabbitmq.ssl.trust-store=classpath:ssl/rabbitmqTrustStorespring.rabbitmq.ssl.trust-store-type=JKS#不校验主机名,默认开启会导致连接失败spring.rabbitmq.ssl.verify-hostname=false

src/main/resources 下创建 ssl 目录,将 客户端证书和服务端JKS公钥复制到 ssl 目录中。

执行代码验证

运行 DemoApplication.java,查看控制台是否有报错:

如图,提示创建连接成功,说明已经连接成功了。

我们再调用 TestController.java 中定义的 /test 接口

消息发送与消费成功。

读到这里,这篇"RabbitMQ如何开启SSL与SpringBoot连接测试"文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注行业资讯频道。

证书 配置 服务 客户 目录 生成 客户端 公钥 测试 验证 位置 密码 成功 代码 参数 文件 消息 主机 文章 监听 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 现代网络技术课程设计 支付宝数据库实力怎么样 深圳五金备件管理软件开发 中国网络安全问题的原因 路由服务器无响应 event软件开发 怎么访问虚拟服务器 大学生网络安全信息素养问卷 聚搜索软件开发 mysql用命令删除数据库 做软件开发容易吗 建立网络安全免疫系统 软件开发项目组表扬信 华为信息和网络技术学院 锐捷网络技术支持怎么样 虚拟服务器传送文件 智恒全新一代网络安全产品面世 网络安全攻防大赛致辞 太仓专业性网络技术服务费 数据库投影选择叫什么意思 华夏人生怎么进不去服务器 医学搜索引擎数据库是什么 局域网自建dns服务器 服务器dl380内存插回不好用 邢台网络存储服务器报价 防城港在线网络技术有限公司招聘 网络安全归市场监管局哪个部门管 软件开发工程师书名 事业单位改网络安全保障中心 在数据库技术中编写应用程序
0