首页 > 解决方案 > Python 中 MQTT over TLS 验证错误(C# 和 Mqtt.fx 中没有错误)

问题描述

我有一个 Mosquitto 服务器配置为使用 MQTT over TLS,使用以下配置,通过 certbot 生成证书和密钥:

user mosquitto
listener 1883 localhost
listener 8883
cafile /etc/letsencrypt/live/my.mqtt.domain/chain.pem
keyfile /etc/letsencrypt/live/my.mqtt.domain/privkey.pem
certfile /etc/letsencrypt/live/my.mqtt.domain/cert.pem

我在使用 paho python 客户端和 mosquitto-clients(mosquitto_sub 和 mosquitto_pub)时遇到问题,而在 C# 或 MQTT.fx GUI 客户端(使用 Paho Java 客户端)中使用 M2MQTT 客户端完全没有问题。

以下是我的python代码:

import paho.mqtt.client as mqtt
import ssl

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

# chain.pem is the exact same file of the mosquitto configuration 
# /etc/letsencrypt/live/my.mqtt.domain/chain.pem
client.tls_set(ca_certs="chain.pem", certfile=None, keyfile=None,
               cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)

client.connect("my.mqtt.domain", 8883, 60)

以下是我尝试运行此代码时出现的错误:

Traceback (most recent call last):
  File "subscriber.py", line 26, in <module>
    client.connect("my.mqtt.domain", 8883, 60)
  File "venv\lib\site-packages\paho\mqtt\client.py", line 839, in connect
    return self.reconnect()
  File "\venv\lib\site-packages\paho\mqtt\client.py", line 994, in reconnect
    sock.do_handshake()
  File "C:\Program Files\Python3\lib\ssl.py", line 1108, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get issuer certificate (_ssl.c:1045)

在服务器端,我得到以下信息:

1540452676: OpenSSL Error: error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca
1540452676: OpenSSL Error: error:140940E5:SSL routines:ssl3_read_bytes:ssl handshake failure

我会想到服务器端的配置错误,但是如果我尝试使用 C# 客户端,使用 M2MQTT,我完全没有问题:

MqttClient client = new MqttClient("my.mqtt.domain", 
    MqttSettings.MQTT_BROKER_DEFAULT_SSL_PORT, 
    true, 
    new X509Certificate("chain.pem"), 
    null, 
    MqttSslProtocols.TLSv1_2);

byte code = client.Connect(new Guid().ToString());

Console.WriteLine(code);
var message = "message";
client.Publish("test", Encoding.UTF8.GetBytes(message), 2, true);

同样,Mqtt.fx 完全没有问题:

Mqtt.fx 客户端配置

都一样,努力

openssl s_client -connect my.mqtt.domain:8883 -CAfile /etc/letsencrypt/live/my.mqtt.domain/chain.pem

工作正常,没有错误并返回代码 0 进行验证。

欢迎任何帮助。

标签: c#python-3.xmqttmosquittopaho

解决方案


证书有一些错误;也许python会严格检查

当您使用 openssl s_client 时,您是否理解了 s_client 回显的所有消息。我在测试 ssl 通信时遇到了一些问题,最后,我发现证书有错误的时间,比如“not before”或“not after”等错误,


推荐阅读