生产环境中,若消息内容敏感或网络链路不可信,必须通过配置 SSL 加密监听 5671 端口,避免明文传输。以下基于 RabbitMQ 3.7+ 版本提供完整实操方案。
先说结论:开启 SSL 需生成 CA 及服务器证书,修改 rabbitmq.conf 配置绝对路径,严格限制私钥权限,客户端连接需信任 CA 证书。
- 版本注意:RabbitMQ 3.7+ 使用 rabbitmq.conf,旧版本使用 advanced.config。
- 核心风险:证书文件权限错误会导致服务启动失败,私钥泄露会导致加密失效。
- 验证关键:使用 openssl s_client 测试握手,客户端代码配置 ssl_options 连接。
版本兼容性说明
本配置适用于 RabbitMQ 3.7 及以上版本,采用新版配置格式。若使用 3.6 或更低版本,配置文件格式为 Erlang 术语格式(advanced.config),配置项写法不同。生产环境建议升级至 3.8+ 以获得更好的 TLS 1.3 支持。
完整证书生成脚本
测试环境可使用 OpenSSL 生成自签名证书,生产环境建议申请受信任的公共 CA 证书。以下脚本包含 CA 生成、服务器证书生成及 CA 签名步骤,修复了仅生成 CSR 导致配置无效的问题。
# 1. 生成 CA 私钥和证书
openssl req -new -x509 -days 365 -nodes -out cacert.pem -keyout cakey.pem# 2. 生成服务器私钥和 CSR 请求
openssl req -new -nodes -out server_cert.csr -keyout server_key.pem# 3. 使用 CA 签名服务器证书 (关键步骤)
openssl x509 -req -days 365 -in server_cert.csr -CA cacert.pem -CAkey cakey.pem -out server_cert.pem# 4. 清理 CSR 文件
rm server_cert.csr将生成的 cacert.pem、server_cert.pem 和 server_key.pem 放置于服务器安全目录,例如 /etc/rabbitmq/certs。
配置文件修改
编辑 /etc/rabbitmq/rabbitmq.conf 文件,添加以下配置。注意路径必须为绝对路径,且文件存在。
# 启用 SSL 监听端口
listeners.ssl.default = 5671# 证书文件路径
ssl_options.cacertfile = /etc/rabbitmq/certs/cacert.pem
ssl_options.certfile = /etc/rabbitmq/certs/server_cert.pem
ssl_options.keyfile = /etc/rabbitmq/certs/server_key.pem# 验证模式:verify_peer 表示要求客户端提供证书,verify_none 表示单向加密
ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = false# 允许的安全协议版本,建议明确指定
ssl_options.versions.1 = tlsv1.2
ssl_options.versions.2 = tlsv1.3权限与安全设置
证书文件权限配置不当是启动失败的最常见原因。私钥文件必须仅属主可读,防止泄露。
# 创建目录
mkdir -p /etc/rabbitmq/certs# 移动证书文件
mv *.pem /etc/rabbitmq/certs/# 修改属主为 rabbitmq 用户
chown -R rabbitmq:rabbitmq /etc/rabbitmq/certs# 设置权限:私钥 600,公钥证书 644
chmod 600 /etc/rabbitmq/certs/server_key.pem
chmod 644 /etc/rabbitmq/certs/server_cert.pem
chmod 644 /etc/rabbitmq/certs/cacert.pem配置完成后重启服务:systemctl restart rabbitmq-server。
客户端连接代码示例
Python (pika)
import pika
import ssl# 加载 CA 证书
context = ssl.create_default_context(cafile="/path/to/cacert.pem")# 配置连接参数
parameters = pika.ConnectionParameters(host='rabbitmq.example.com',port=5671,ssl_options=pika.SSLOptions(context, server_hostname='rabbitmq.example.com')
)connection = pika.BlockingConnection(parameters)Java (Spring Boot)
# application.yml 配置
spring:rabbitmq:host: rabbitmq.example.comport: 5671ssl:enabled: trueverify-hostname: true# 信任库路径,需将 cacert.pem 导入 keystoretrust-store: /path/to/truststore.jkstrust-store-password: changeit验证方法
1. 端口监听检查
使用 ss 命令确认 5671 端口处于监听状态:ss -tlnp | grep 5671。
2. OpenSSL 握手测试
执行以下命令,观察 handshake 是否成功及证书链返回情况:
openssl s_client -connect 服务器 IP:5671 -CAfile /etc/rabbitmq/certs/cacert.pem若返回 Verify return code: 0 (ok) 则表示验证通过。
3. 客户端连通性
运行上述客户端代码,若能成功建立连接并发布/消费消息,则配置生效。
常见坑与排查
1. 证书权限问题
日志报 permission denied,通常是 rabbitmq 用户无权读取 key 文件。确保 key 文件属主正确且权限为 600。
2. CN 或 SAN 不匹配
证书中的 Common Name 或 Subject Alternative Name 必须包含客户端连接使用的域名。若使用 IP 连接,需在生成证书时将 IP 加入 SAN,否则客户端会报 hostname mismatch。
3. 客户端未信任 CA
服务端开启 verify_peer 后,客户端必须配置信任对应的 CA 证书,否则连接会被拒绝。自签名证书需手动分发 CA 公钥给客户端。
4. 协议版本兼容
旧版客户端可能不支持 TLS 1.2 或 1.3。若连接失败,检查服务端 ssl_options.versions 配置,必要时临时允许 tlsv1 但存在安全风险。
5. 生产环境证书链
若使用公共 CA 证书,可能需要配置 ssl_options.certfile 为完整证书链(服务器证书 + 中间证书),否则部分客户端验证会失败。
原文链接:https://www.zjcp.cc/ask/11567.html
