You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Python应用通过TLS连接RabbitMQ(MQTT插件)的证书验证失败问题

问题:Python连接RabbitMQ MQTT插件的TLS证书验证失败?

我使用带有MQTT插件的RabbitMQ,配置如下:

loopback_users.guest = false
listeners.tcp = none
listeners.ssl.default = 5671
password_hashing_module = rabbit_password_hashing_sha512

# General
ssl_options.cacertfile = /etc/rabbitmq/cert/ca_certificate.pem
ssl_options.certfile   = /etc/rabbitmq/cert/server_certificate.pem
ssl_options.keyfile    = /etc/rabbitmq/cert/server_key.pem
ssl_options.verify     = verify_peer
ssl_options.fail_if_no_peer_cert  = true

# Web
management.ssl.port = 15672
management.ssl.cacertfile = /etc/rabbitmq/cert/ca_certificate.pem
management.ssl.certfile   = /etc/rabbitmq/cert/server_certificate.pem
management.ssl.keyfile    = /etc/rabbitmq/cert/server_key.pem
management.load_definitions = /etc/rabbitmq/definitions.json


# Mqtt plugin
mqtt.allow_anonymous = false
mqtt.listeners.ssl.default = 8883
mqtt.listeners.tcp.default = 1883 

证书无误,Web端安全连接正常。我尝试用Python应用通过TLS连接RabbitMQ,代码如下:

PATH_CERT = '/<path>/server_certificate.pem'
client = paho.Client()
client.on_connect = on_connect
client.on_publish = on_publish
client.on_message = on_message
client.username_pw_set(MQTT_USER, MQTT_PASSWORD)
client.tls_set(ca_certs = PATH_CERT, tls_version=ssl.PROTOCOL_TLSv1_2)
client.tls_insecure_set(False)
client.connect('my.domain.pl', 8883, 60)
client.loop_forever()

但出现错误:

File "/usr/lib/python3.8/ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1131)

用户名、密码及域名均正确,请问如何解决该证书问题?Python中传入的证书是否正确?


解决方案

你当前代码里传入的证书是错误的。tls_set的ca_certs参数需要传入的是CA根证书(ca_certificate.pem),而非服务器证书(server_certificate.pem)。

原因说明

TLS握手时,客户端需要通过CA根证书验证服务器证书的合法性:服务器证书由CA签发,客户端只有持有对应的CA根证书,才能确认服务器证书是可信的。你现在传递的是服务器证书,无法完成签发者(issuer)的验证流程,因此触发证书验证失败的错误。

修复步骤

  1. 将PATH_CERT替换为CA根证书的本地路径,确保该文件与RabbitMQ配置中使用的/etc/rabbitmq/cert/ca_certificate.pem是同一个文件,且未损坏。
  2. 修改后的核心代码片段:
# 替换为CA根证书的路径
PATH_CA_CERT = '/<path>/ca_certificate.pem'
client = paho.Client()
# 回调函数、用户名密码配置保持不变
client.tls_set(ca_certs = PATH_CA_CERT, tls_version=ssl.PROTOCOL_TLSv1_2)
client.tls_insecure_set(False)
client.connect('my.domain.pl', 8883, 60)
client.loop_forever()

额外注意事项

  • 确认服务器证书的CN(通用名称)或SAN(主题备用名称)包含你连接使用的域名my.domain.pl,否则即使CA证书正确,仍可能出现验证失败。
  • 不要随意开启client.tls_insecure_set(True),这会跳过证书验证环节,带来安全风险。

内容的提问来源于stack exchange,提问作者Ploxer2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 04:37:32