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

GoLang Mochi MQTT与Python Paho客户端TLS认证失败排查

问题原因分析

两个报错的核心都是双向TLS认证中,服务端与客户端未正确配置信任本地根CA证书:

  1. 服务端报错read connection: remote error: tls: unknown certificate authority:服务端未将本地根CA加入信任池,无法验证客户端证书的签发者合法性。
  2. 客户端报错ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate:客户端未指定信任本地根CA,无法验证服务端证书的完整签发链。
解决步骤

一、确认证书文件完整性

确保你已准备好以下文件(均由本地根CA签发):

  • 根CA证书(例:ca.crt)
  • 服务端证书+私钥(例:server.crt、server.key)
  • 客户端证书+私钥(例:client.crt、client.key)

二、Mochi MQTT服务端配置修正

双向认证需强制要求客户端提供证书,并指定信任的根CA:

package main

import (
    "crypto/tls"
    "crypto/x509"
    "log"
    "os"

    "github.com/mochi-mqtt/server/v2"
    "github.com/mochi-mqtt/server/v2/hooks/auth"
)

func main() {
    // 加载根CA证书到信任池
    caCertBytes, err := os.ReadFile("./ca.crt")
    if err != nil {
        log.Fatalf("failed to read CA cert: %v", err)
    }
    caPool := x509.NewCertPool()
    if !caPool.AppendCertsFromPEM(caCertBytes) {
        log.Fatal("failed to add CA cert to pool")
    }

    // 加载服务端证书和私钥
    serverCert, err := tls.LoadX509KeyPair("./server.crt", "./server.key")
    if err != nil {
        log.Fatalf("failed to load server cert: %v", err)
    }

    // 配置TLS双向认证
    tlsCfg := &tls.Config{
        Certificates: []tls.Certificate{serverCert},
        ClientCAs:    caPool, // 指定信任的根CA,用于验证客户端证书
        ClientAuth:   tls.RequireAndVerifyClientCert, // 强制验证客户端证书
        MinVersion:   tls.VersionTLS12,
    }

    // 启动带TLS的MQTT服务
    s := server.New(server.WithTCPListener(":8883", tlsCfg))
    if err := s.Serve(); err != nil {
        log.Fatalf("server error: %v", err)
    }
}

关键配置:ClientCAs绑定根CA信任池,ClientAuth设为tls.RequireAndVerifyClientCert,确保服务端仅接受本地CA签发的客户端证书。

三、Python Paho客户端配置修正

客户端需同时指定自身证书、私钥,以及用于验证服务端的根CA:

import ssl
import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
    print(f"连接成功,返回码: {rc}")

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
# 配置TLS双向认证参数
client.tls_set(
    ca_certs="./ca.crt",       # 信任的根CA证书
    certfile="./client.crt",   # 客户端证书
    keyfile="./client.key",    # 客户端私钥
    cert_reqs=ssl.CERT_REQUIRED,
    tls_version=ssl.PROTOCOL_TLSv1_2
)
# 本地测试时,若服务端证书CN不是localhost,可临时开启(生产环境禁用)
# client.tls_insecure_set(True)

client.connect("localhost", 8883, 60)
client.loop_forever()

注意:ca_certs必须指定本地根CA路径,否则客户端无法验证服务端证书的合法性。

四、额外检查项

  • 证书权限:Windows下确保程序能读取证书文件(避免放在C盘系统目录等受权限保护的位置)
  • 证书有效期:确认根CA、服务端、客户端证书均在有效期内
  • 证书链:验证客户端/服务端证书能通过根CA完成链上验证

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 20:00:05