RabbitMQ配置SSL

本文详细介绍了如何在Docker环境下安装RabbitMQ并配置SSL,包括证书生成、容器配置以及客户端证书制作。同时,提供了SpringBoot和Python集成RabbitMQ SSL的示例,确保了安全的TLS通信。在配置过程中,强调了证书权限设置和错误排查的重要性。
摘要由CSDN通过智能技术生成

引言

主要介绍了如何通过Docker安装RabbitMQ并配置SSL;配置成功之后给出了SpringBoot和Python集成的例子。

生成证书

$ git clone https://github.com/Berico-Technologies/CMF-AMQP-Configuration.git
$ cd CMF-AMQP-Configuration/ssl/
# Greyfoss 为自定义的证书签发机构名称,该脚本会生成一个ca目录,存储证书颁发机构的信息以及签发的证书
$ sh setup_ca.sh Greyfoss
# 生成服务端公钥和私钥 rabbit-server为生成的密钥前缀  123456为该秘钥自定义的密码
$ sh make_server_cert.sh rabbit-server 123456
# 生成客户端公钥和私钥 
$ sh create_client_cert.sh rabbit-client 123456

生成Java客户端需要的证书

使用java的keytool工具生成客户端需要的证书。

 keytool -import -alias rabbit-server -file server/rabbit-server.cert.pem -keystore server.keystore -storepass 123456
  • import 将已签名数字证书导入密钥库
  • alias 指定导入条目的别名
  • file 指定要导入的证书
  • keystore 指定密钥库的名称
  • storepass 指定生成密钥库的密码

运行该命令会生成密钥库文件server.keystore

安装Rabbitmq配置SSL

先启动rabbitmq容器

docker run --name rabbitmq --restart=unless-stopped -d -p 5672:5672 -p 15672:15672   rabbitmq:management

在宿主机上创建以下文件夹:

 mkdir -p ~/rabbitmq/etc/rabbitmq/ssl

拷贝容器中的文件到宿主机~/rabbitmq/etc/rabbitmq/目录下:

$ docker cp rabbitmq:/etc/rabbitmq/conf.d ~/rabbitmq/etc/rabbitmq/
$ docker cp rabbitmq:/etc/rabbitmq/enabled_plugins ~/rabbitmq/etc/rabbitmq/
$ docker cp rabbitmq:/etc/rabbitmq/rabbitmq.conf ~/rabbitmq/etc/rabbitmq/

拷贝需要的证书到~/rabbitmq/etc/rabbitmq/ssl

$ cp server/rabbit-server.cert.pem ~/rabbitmq/etc/rabbitmq/ssl/
$ cp server/rabbit-server.key.pem ~/rabbitmq/etc/rabbitmq/ssl/
$ cp ca/cacert.pem ~/rabbitmq/etc/rabbitmq/ssl/

编辑~/rabbitmq/etc/rabbitmq/rabbitmq.conf文件,替换为以下内容:

# 禁用非tls连接
listeners.tcp = none
# SSL\TLS通信的端口
listeners.ssl.default = 5671
# 管理控制台端口
management.tcp.port = 15672

# 服务端私钥和证书文件配置
ssl_options.cacertfile = /etc/rabbitmq/ssl/cacert.pem
ssl_options.certfile   = /etc/rabbitmq/ssl/rabbit-server.cert.pem
ssl_options.keyfile    = /etc/rabbitmq/ssl/rabbit-server.key.pem
# 有verify_none和verify_peer两个选项,verify_none表示完全忽略验证证书的结果,verify_peer表示要求验证对方证书
ssl_options.verify     = verify_peer
# 若为true,服务端会向客户端索要证书,若客户端无证书则中止SSL握手;若为false,则客户端没有证书时依然可完成SSL握手
ssl_options.fail_if_no_peer_cert = true
# 指定开启的tls版本
ssl_options.versions.1=tlsv1.2
ssl_options.versions.2=tlsv1.1
# 指定对应的cipher suites
ssl_options.ciphers.1 = ECDHE-ECDSA-AES256-GCM-SHA384
ssl_options.ciphers.2 = ECDHE-RSA-AES256-GCM-SHA384
ssl_options.ciphers.3 = ECDHE-ECDSA-AES256-SHA384
ssl_options.ciphers.4 = ECDHE-RSA-AES256-SHA384
ssl_options.ciphers.5 = ECDHE-ECDSA-DES-CBC3-SHA
ssl_options.ciphers.6 = ECDH-ECDSA-AES256-GCM-SHA384
ssl_options.ciphers.7 = ECDH-RSA-AES256-GCM-SHA384
ssl_options.ciphers.8 = ECDH-ECDSA-AES256-SHA384
ssl_options.ciphers.9 = ECDH-RSA-AES256-SHA384
ssl_options.ciphers.10 = DHE-DSS-AES256-GCM-SHA384
ssl_options.ciphers.11= DHE-DSS-AES256-SHA256
ssl_options.ciphers.12 = AES256-GCM-SHA384
ssl_options.ciphers.13 = AES256-SHA256
ssl_options.ciphers.14 = ECDHE-ECDSA-AES128-GCM-SHA256
ssl_options.ciphers.15 = ECDHE-RSA-AES128-GCM-SHA256
ssl_options.ciphers.16 = ECDHE-ECDSA-AES128-SHA256
ssl_options.ciphers.17 = ECDHE-RSA-AES128-SHA256
ssl_options.ciphers.18 = ECDH-ECDSA-AES128-GCM-SHA256
ssl_options.ciphers.19= ECDH-RSA-AES128-GCM-SHA256
ssl_options.ciphers.20 = ECDH-ECDSA-AES128-SHA256
ssl_options.ciphers.21 = ECDH-RSA-AES128-SHA256
ssl_options.ciphers.22 = DHE-DSS-AES128-GCM-SHA256
ssl_options.ciphers.23 = DHE-DSS-AES128-SHA256
ssl_options.ciphers.24 = AES128-GCM-SHA256
ssl_options.ciphers.25 = AES128-SHA256
ssl_options.ciphers.26 = ECDHE-ECDSA-AES256-SHA
ssl_options.ciphers.27 = ECDHE-RSA-AES256-SHA
ssl_options.ciphers.28 = DHE-DSS-AES256-SHA
ssl_options.ciphers.29 = ECDH-ECDSA-AES256-SHA
ssl_options.ciphers.30 = ECDH-RSA-AES256-SHA
ssl_options.ciphers.31= AES256-SHA
ssl_options.ciphers.32 = ECDHE-ECDSA-AES128-SHA
ssl_options.ciphers.33 = ECDHE-RSA-AES128-SHA
ssl_options.ciphers.34 = DHE-DSS-AES128-SHA
ssl_options.ciphers.35 = DHE-DSS-AES128-SHA256
ssl_options.ciphers.36 = ECDH-ECDSA-AES128-SHA
ssl_options.ciphers.37 = ECDH-RSA-AES128-SHA
ssl_options.ciphers.38 = AES128-SHA

删除正在运行的rabbitmq:

docker rm -f rabbitmq

使用下面命令重新创建rabbitmq容器

docker run --restart=unless-stopped -d  \
        -p 15672:15672 -p 5671:5671  \
        -v  /home/yjw/rabbitmq/etc/rabbitmq/:/etc/rabbitmq/   \
        --name rabbitmq \
        rabbitmq:management

docker logs -f rabbitmq 看到日志内以下内容说明配置成功。

2021-07-09 02:47:14.453 [info] <0.882.0> started TLS (SSL) listener on [::]:5671
{removed_failing_handler,rabbit_log}
2021-07-09 02:47:17.092 [info] <0.736.0> Server startup complete; 4 plugins started.
 * rabbitmq_prometheus
 * rabbitmq_management
 * rabbitmq_web_dispatch
 * rabbitmq_management_agent
 completed with 4 plugins.
2021-07-09 02:47:17.093 [info] <0.736.0> Resetting node maintenance status

默认的guest用户不能远程访问,因此需要创建一个可以远程访问的用户。

# 进入容器内部
$ docker exec -it rabbitmq bash

# 创建一个用户名为rabbit,密码为rabbit的用户
$ rabbitmqctl add_user rabbit rabbit

# 设置用户权限为超级管理员
$ rabbitmqctl set_user_tags rabbit administrator

# 授权远程访问
$ rabbitmqctl set_permissions -p / rabbit "." "." ".*"

# 退出容器
$ exit

# 重启rabbitmq
$ docker restart rabbitmq

通过刚才创建的用户rabbit访问管理员页面http://ip:15672

在这里插入图片描述

看到amqp/ssl 5671说明配置成功! 🥳

SpringBoot集成RabbitMQ SSL

首先在配置文件中添加以下配置,比如在application-dev.yaml中添加:

spring:
  rabbitmq:
    virtual-host: /
    host: 127.0.0.1
    port: 5671
    username: ${RABBIT_USERNAME}
    password: ${RABBIT_PASSWORD}
    ssl:
      enabled: true
      key-store: classpath:keyStore/rabbit-client.keycert.p12
      key-store-password: ${KEYSTORE_PASSWORD}
      trust-store: classpath:keyStore/server.keystore
      trust-store-password: ${TRUSTSTORE_PASSWORD}
      algorithm: TLSv1.2
      verify-hostname: false

其中${RABBIT_USERNAME}等配置在系统变量中。

比较简单,只要导入依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration类就会自动配置。

Python 集成RabbitMQ SSL

import logging
import pika
import ssl



# 请替换所有证书路径
# 以下证书分别在目录 ~/rabbitmq/etc/rabbitmq/ssl/ sa和client文件下
ca_certfile = "certs/cacert.pem"
certfile = "certs/rabbit-client.cert.pem"
private_key = "certs/rabbit-client.key.pem"
# 服务器信息
hostname = "127.0.0.1"
port = 5671

# logging.basicConfig(level=logging.INFO)


credentials = pika.credentials.PlainCredentials('rabbit', 'rabbit')

context = ssl.create_default_context(cafile=ca_certfile)

# 注意:由于证书是不受信任的,因此必须要关闭证书验证,否则会运行报错,提示证书验证失败!
context = ssl._create_unverified_context()

context.load_cert_chain(certfile, private_key)
ssl_options = pika.SSLOptions(context, hostname)

conn_params = pika.ConnectionParameters(host=hostname,port=port, ssl_options=ssl_options,credentials=credentials)

with pika.BlockingConnection(conn_params) as conn:
    ch = conn.channel()
    ch.queue_declare("ssl_test")
    ch.basic_publish("", "ssl_test", "Hello, world!")
    conn.close()

FAQ

启动rabbitmq容器失败,报ssl_options.keyfile invalid, file does not exist or cannot be read by the node

启动后查看容器日志,发现以下报错:

02:56:48.341 [error] ssl_options.keyfile invalid, file does not exist or cannot be read by the node
02:56:48.351 [error] Error preparing configuration in phase validation:
02:56:48.351 [error]   - ssl_options.keyfile invalid, file does not exist or cannot be read by the node
02:56:48.356 [error] 
02:56:48.356 [error] BOOT FAILED

进入宿主机下~/rabbitmq/etc/rabbitmq/ssl目录,确定cacert.pemrabbit-server.cert.pemrabbit-server.key.pem的读写权限。

$ ll
total 24
drwxrwxr-x 2 yjw yjw 4096 Jul  9 09:58 ./
drwxrwxr-x 4 yjw yjw 4096 Jul  9 10:25 ../
-rw-rw-r-- 1 yjw yjw 1046 Jul  9 09:56 cacert.pem
-rw------- 1 yjw yjw 2349 Jul  9 09:58 rabbit-client.keycert.p12
-rw-rw-r-- 1 yjw yjw 1070 Jul  9 09:56 rabbit-server.cert.pem
-rw------- 1 yjw yjw 1675 Jul  9 09:56 rabbit-server.key.pem

这里就需要把rabbit-server.key.pem的读写权限设成和其他两个一样。

$ chmod 664 rabbit-server.key.pem
要在Spring Boot中配置SSL访问RabbitMQ,需要遵循以下步骤: 1. 生成证书 首先,需要生成一个证书,用于启用SSL连接。可以使用以下命令生成一个自签名的证书: ``` keytool -genkeypair -alias rabbitmq -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore rabbitmq.p12 -validity 3650 ``` 该命令将生成一个名为`rabbitmq.p12`的证书文件。在生成证书时,需要注意以下几点: - `alias`参数用于指定证书别名,可以根据需要进行更改。 - `storetype`参数用于指定证书存储类型,这里使用`PKCS12`格式。 - `validity`参数用于指定证书有效期,这里为10年。 2. 配置RabbitMQ 接下来,需要在RabbitMQ上启用SSL连接。在RabbitMQ服务器上,需要将证书文件`rabbitmq.p12`复制到`/etc/rabbitmq/ssl`目录中,并将其权限设置为`644`。然后,需要创建一个RabbitMQ配置文件,指定SSL参数和证书路径: ``` ssl_options.verify = verify_peer ssl_options.fail_if_no_peer_cert = false ssl_options.cacertfile = /etc/rabbitmq/ssl/ca_certificate.pem ssl_options.certfile = /etc/rabbitmq/ssl/server_certificate.pem ssl_options.keyfile = /etc/rabbitmq/ssl/server_key.pem ssl_options.password = password ssl_options.versions = ['tlsv1.2'] ``` 其中,`cacertfile`参数指定CA证书路径,`certfile`参数指定服务器证书路径,`keyfile`参数指定服务器私钥路径,`password`参数指定证书密码。`versions`参数指定支持的TLS版本。 3. 在Spring Boot中启用SSL连接 最后,需要在Spring Boot应用程序中启用SSL连接。可以在`application.properties`文件中添加以下配置: ``` spring.rabbitmq.ssl.enabled=true spring.rabbitmq.ssl.key-store-type=PKCS12 spring.rabbitmq.ssl.key-store=classpath:rabbitmq.p12 spring.rabbitmq.ssl.key-store-password=password spring.rabbitmq.ssl.trust-store-type=PEM spring.rabbitmq.ssl.trust-store=classpath:ca_certificate.pem ``` 其中,`key-store-type`参数指定证书类型,`key-store`参数指定证书路径,`key-store-password`参数指定证书密码。`trust-store-type`参数指定CA证书类型,`trust-store`参数指定CA证书路径。 现在,应用程序应该能够使用SSL连接到RabbitMQ了。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愤怒的可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值