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

Mosquitto Broker TLS连接报sslv3 alert bad certificate错误

问题根因

两端报错是同一个问题触发的连锁反应,核心原因如下:

  • 你当前部署的broker服务端证书为X.509 Version 1 版本,该版本标准不支持Subject Alternative Name (SAN,主题备用名称)扩展字段,且你贴出的证书有效期到2023年7月9日,本身已经过期。
  • Python标准库ssl模块和mosquitto_pub的证书校验逻辑存在本质差异:
    • mosquitto_pub调用原生OpenSSL接口做校验,当证书不存在SAN字段时,会回退读取证书Subject中的CN字段做匹配,你证书CN值正好是192.168.1.254,和连接时用的IP一致,所以命令行连接无报错。
    • Python的ssl模块从3.7版本开始严格遵循RFC 5280标准,仅从SAN扩展字段读取待匹配的IP/域名,完全不会回退校验CN字段内容,因此直接抛出「IP address mismatch」错误;客户端校验失败后会向broker发送错误告警,broker端日志就对应显示sslv3 alert bad certificate——这个报错不是指你的客户端证书有问题,只是broker记录收到的客户端告警而已。
  • 你的Python脚本存在两处配置笔误:
    • 脚本中写的CA证书路径是/etc/mosquitto/ca.pem、客户端证书路径是/etc/mosquitto/VM.pem,但你正常连通的命令行用的是ca.crt和VM.crt,文件名不匹配会直接导致证书加载失败。
    • 调用tls_set()时仅传入了CA证书参数,没有加载双向TLS认证需要的客户端证书、客户端密钥参数,即使证书校验通过也会因为缺少客户端凭证被broker拒绝。
修复步骤
  • 第一步:重新签发带SAN扩展的X.509 v3版本服务端证书
    签发时必须在OpenSSL配置中添加v3扩展段,把树莓派IP写入SAN字段,示例配置片段如下:
    [v3_ext]
    basicConstraints = CA:FALSE
    keyUsage = digitalSignature, keyEncipherment
    extendedKeyUsage = serverAuth
    subjectAltName = IP:192.168.1.254
    # 如果后续需要用域名连接,可追加DNS记录,例如:
    # subjectAltName = IP:192.168.1.254,DNS:raspberrypi.local
    
    签发服务端证书时添加-extensions v3_ext参数,确保证书生成时加载上述扩展配置,同时把证书有效期设置为合理时长。
  • 第二步:校验新证书有效性
    签发完成后执行命令校验证书内容:
    openssl x509 -in 新服务端证书路径 -text -noout
    
    确认输出满足两个要求:
    • 证书版本显示为Version: 3 (0x2)
    • 扩展字段中存在X509v3 Subject Alternative Name条目,且内容包含IP Address:192.168.1.254
  • 第三步:修正Python脚本配置
    统一证书文件名和实际路径,补全客户端证书、密钥的加载参数,修正后示例代码如下:
    import ssl
    import paho.mqtt.client as mqtt
    
    # 和命令行使用的证书路径、文件名保持完全一致
    TLS_CERT_PATH = "/etc/mosquitto/ca.crt"
    client_crt = "/etc/mosquitto/VM.crt"
    client_key = "/etc/mosquitto/parrot.key"
    
    client = mqtt.Client()
    client.tls_set(
        ca_certs=TLS_CERT_PATH,
        certfile=client_crt, # 补全客户端证书参数
        keyfile=client_key,  # 补全客户端密钥参数
        cert_reqs=ssl.CERT_REQUIRED,
        tls_version=ssl.PROTOCOL_TLSv1_2,
        ciphers=None
    )
    client.tls_insecure_set(False)
    client.connect("192.168.1.254", 2259, 60)
    client.loop_forever()
    
  • 第四步:重启mosquitto服务加载新的服务端证书,再运行Python脚本即可正常连接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:12:45