使用 TLS 保护客户端连接

当生产者、消费者、自动化工具或管理员通过不受信任的网络、外部 主机端口负载均衡器,或者跨集群连接到 RabbitMQ 时,请使用 TLS。TLS 可保护 AMQP 流量和管理 HTTP API,避免以明文传输。

本指南介绍用于客户端访问的 RabbitMQ 监听器 TLS。它不能替代用户、虚拟主机或权限控制。请在生产工作负载中同时配置 TLS 和最小权限的 RabbitMQ 用户。

前提条件

在启用 TLS 之前,请确保满足以下条件:

  1. 你有一个 RabbitmqCluster 实例。
  2. 你有供客户端使用的 RabbitMQ 访问名称对应的服务器证书和私钥。
  3. 证书的 Subject Alternative Name 包含集群内服务的 DNS 名称,以及客户端使用的任何外部 DNS 名称或 IP 地址。
  4. 如果客户端必须验证私有 CA,你已经有 CA 证书。
  5. 在禁用非 TLS 监听器后,应用已准备好使用 amqps:// 和 TLS 管理端点。
规划监听器变更

spec.tls.disableNonTLSListeners 设置为 true 会为 RabbitMQ、management 插件以及受支持的协议插件禁用非 TLS 监听器。仅当所有客户端和运维工具都能够使用 TLS 端点后再启用此设置。

操作步骤

1. 创建 TLS secret

在与 RabbitmqCluster 相同的 namespace 中创建 TLS secret:

kubectl -n <namespace> create secret tls rabbitmq-server-tls \
  --cert=path/to/tls.crt \
  --key=path/to/tls.key

如果客户端使用私有 CA,请创建 CA secret:

kubectl -n <namespace> create secret generic rabbitmq-ca \
  --from-file=ca.crt=path/to/ca.crt

2. 配置 RabbitmqCluster

更新 RabbitmqCluster 以引用 TLS secret。当 broker 必须信任私有 CA 以进行双向 TLS,或者为了 web_stompweb_mqtt 等相关协议插件时,请包含 caSecretName。外部 AMQP 或管理客户端仍然需要在其自己的信任存储中包含 CA 证书。

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
  name: <instance-name>
  namespace: <namespace>
spec:
  tls:
    secretName: rabbitmq-server-tls
    caSecretName: rabbitmq-ca
    disableNonTLSListeners: true

如果你正在迁移现有客户端,请在迁移窗口期间保持 disableNonTLSListeners 未设置,或者将其设置为 false。在所有客户端都使用 TLS 之后,将该字段更新为 true

3. 等待滚动更新完成

等待实例返回到 active 阶段,并且所有 RabbitMQ Pod 都处于就绪状态:

kubectl -n <namespace> get rabbitmqcluster <instance-name>

kubectl -n <namespace> get pods \
  -l app.kubernetes.io/name=<instance-name>

4. 验证 TLS 监听器

从 RabbitMQ Pod 中检查监听器列表:

kubectl -n <namespace> exec <instance-name>-server-0 -- \
  rabbitmq-diagnostics listeners

对于仅 TLS 配置,输出应包含 TLS 监听器,并且不应再显示已禁用协议的纯 AMQP 或纯 HTTP 监听器。

同时验证暴露给客户端的 Kubernetes Service 端口:

kubectl -n <namespace> get svc <instance-name>

5. 使用 TLS 连接

AMQP 客户端请使用 amqps://

amqps://<username>:<password>@<rabbitmq-host>:5671/%2f

%2f 是默认 / 虚拟主机的 URL 编码形式。请将其替换为你的应用所使用的 URL 编码虚拟主机。

在针对 management API 运行 rabbitmqadmin 时,请使用 TLS 选项:

rabbitmqadmin \
  --host <rabbitmq-host> \
  --port <tls-management-port> \
  --ssl \
  --ssl-ca-cert-file path/to/ca.crt \
  --username <username> \
  --password <password> \
  list queues name messages consumers

如果客户端证书、密钥或 CA 路径错误,rabbitmqadmin 会在向 RabbitMQ 进行身份验证之前失败。

验证

启用 TLS 后,请使用以下检查项:

检查命令预期结果
RabbitmqCluster 接受 TLS speckubectl -n <namespace> get rabbitmqcluster <instance-name> -o yamlspec.tls.secretName 的值引用了 TLS secret。
Pod 已完成滚动更新kubectl -n <namespace> get pods -l app.kubernetes.io/name=<instance-name>所有 RabbitMQ Pod 均为 Ready
TLS 监听器已激活kubectl -n <namespace> exec <instance-name>-server-0 -- rabbitmq-diagnostics listeners对于你启用的协议,TLS 监听器已存在。
客户端可以连接客户端特定的健康检查或 rabbitmqadmin --ssl ... list queues客户端连接时没有证书或主机名验证错误。

故障排查

症状可能原因建议
客户端报告主机名验证失败证书不包含客户端使用的服务 DNS 名称或外部地址。使用 Subject Alternative Name 中所有必需的 DNS 名称和 IP 地址重新签发证书。
客户端报告未知 CA 错误客户端不信任签发服务器证书的 CA。将 CA 证书分发给客户端,并配置客户端信任存储。
在禁用非 TLS 监听器后管理命令失败运维工具仍在使用纯 HTTP management 端点。更新工具以使用 --ssl、TLS 管理端口以及 CA 证书。
切换到 amqps:// 后应用无法连接端口、URI 编码、vhost 或凭证值与 TLS 监听器不匹配。验证监听器列表、Service 端口、虚拟主机、用户权限以及 URL 编码。

相关信息