I have a Mosquitto server configured to use MQTT over TLS, using the following configuration, with certificates and keys generated through 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
I'm having trouble with the paho python client and mosquitto-clients (mosquitto_sub and mosquitto_pub), whereas I have no trouble at all using the M2MQTT client in C# or MQTT.fx GUI client (which uses Paho Java client).
The following is my python code:
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)
And the following is the error I get trying to run this code:
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)
while on the server side I get the following:
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
I would have thought of a configuration error server side, but if I try to use a C# client, with M2MQTT, I have no problem at all:
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);
and, all the same, no issue at all with Mqtt.fx:
All the same, trying
openssl s_client -connect my.mqtt.domain:8883 -CAfile /etc/letsencrypt/live/my.mqtt.domain/chain.pem
works fine, with no error and return code 0 for the verification.
Any help is welcome.