irpas技术客

【亲测可用】禁用AMQP配置中的明文身份验证机制-漏洞解决方法(RabbitMQ开启SSL附SpringBoot连接测试代码)_东北小狐狸-Hellxz_amq

网络 6023

楔子

近期公司程序被安全扫描出 远程主机允许明文身份验证 中风险漏洞,查了下修复方案发现网上的都是把 RabbitMQ 的认证机制改了,然后也没提供 Java 客户端连接测试结果,底下全是登录失败的回帖……

想到 RabbitMQ 官方提供了SSL连接方式,而且 SpringBoot AMQP 也支持 SSL 连接,所以尝试以下将配置RabbitMQ开启SSL 并使用 SpringBoot Demo 测试连接。最终修复了这个漏洞,同时 Java 客户端连接正常。

文章修订日志:

2022-01-07 21:59写文章时此配置还未安全扫描复测,如果测试通过,本人将更新此文章状态为验证通过。2022-01-11 14:36 复测不通过,修正文章,调整认证机制为 EXTERNAL 与 插件认证方式,等待复测。2022-01-11 17:28 复测通过。 配置 RabbitMQ 开启 SSL

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

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

以上生成的客户端证书的CN为 rabbitmq-client,此名称会被 RabbitMQ服务端作为登录名使用,需要提前创建此用户以及给予权限。

配置 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" ]} ]}, {auth_mechanisms,['EXTERNAL']}, {ssl_cert_login_from,common_name} ]}].

主要配置项说明:

ssl_listeners 指定 SSL协议的端口号,官方文档 5671ssl_options SSL 认证配置项 cacertfile CA 证书位置certfile 公钥证书位置keyfile 密钥证书位置verify verify_peer 客户端与服务端互相发送证书verify_none 禁用证书交换与校验 fail_if_no_peer_cert true 不接受没证书的客户端连接false 接受没证书的客户端连接 ciphers 加密器(这个翻译不知道算不算对?) auth_mechanisms 认证机制,此处使用 EXTERNAL 表示只使用插件提供认证功能ssl_cert_login_from 使用证书中的哪些信息登录,如果不配置这项是走的DN,配置走CN common_name CN名称 启用插件 #启用rabbitmq_auth_mechanism_ssl作为EXTERNAL认证机制的实现 rabbitmq-plugins enable rabbitmq_auth_mechanism_ssl #查看启动结果 rabbitmq-plugins list

重启 RabbitMQ #关闭 rabbitmqctl stop #启动 rabbitmq-server -detached 添加证书登录用户与授权 #添加证书登录用户(用户名要与客户端证书名称前缀一致),密码任意 rabbitmqctl add_user 'rabbitmq-client' '2a55f70a841f18b97c3a7db939b7adc9e34a0f1b' #给rabbitmq-client用户虚拟主机/的所有权限,如需其他虚拟主机替换/ rabbitmqctl set_permissions -p "/" "rabbitmq-client" ".*" ".*" ".*" 验证开启 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

2022.02.10更新:由于读者反应测试代码行为不正常(原因是目录结构放得不对!),现已将测试代码已上传本人GitHub https://github.com/hellxz/rabbitmq-ssl-demo , 使用时注意替换证书文件!

代码及配置

pom.xml

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://·blogs.com/ybyn/p/13959135.html

本文同步于本人博客园(hellxz.cnblogs.com) 与 CSDN(https://blog.csdn.net/u012586326),禁止转载。


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #amqp明文验证 #楔子近期公司程序被安全扫描出 #远程主机允许明文身份验证 #springboot #amqp #也支持 #SSL