c# - 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 完全没有问题:
都一样,努力
openssl s_client -connect my.mqtt.domain:8883 -CAfile /etc/letsencrypt/live/my.mqtt.domain/chain.pem
工作正常,没有错误并返回代码 0 进行验证。
欢迎任何帮助。
解决方案
证书有一些错误;也许python会严格检查
当您使用 openssl s_client 时,您是否理解了 s_client 回显的所有消息。我在测试 ssl 通信时遇到了一些问题,最后,我发现证书有错误的时间,比如“not before”或“not after”等错误,
推荐阅读
- javascript - 基于 Datatable Jquery 的插件 - 表格 - 表格中可折叠的问题 - Javascript/HTML
- laravel - laravel nova 观察者试图获取非对象的属性
- gitlab-ci-runner - 错误:准备失败:Getwd:getwd:没有这样的文件或目录
- python - 如何为熊猫数据框中的切片分配值
- php - 如何修复 .htaccess 错误?一直要求认证
- css - 在 CSS Grid 项目中定位元素
- excel - 提取二维数组中的重复条目
- c++ - 如何从多条直线中画出一条曲线?
- arrays - 试图获取对象数组中对象内部对象的键值的长度
- python - 使用对象查询 pandas 数据框