0

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:

Mqtt.fx client configuration

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.

fedexist
  • 155
  • 2
  • 12
  • Try `fullchain.pem` not `chain.pem` – hardillb Oct 25 '18 at 09:38
  • Hi, I just tried and using `fullchain.pem` is no use: python code gives the same error, and C# & Mqtt.fx keep working. – fedexist Oct 25 '18 at 09:49
  • Sorry, missed it earlier, you should be using full chain in the mosquitto.conf as well iirc – hardillb Oct 25 '18 at 09:50
  • Unfortunately, same errors and nothing changes. – fedexist Oct 25 '18 at 10:02
  • 1
    Sounds like you need to import the LetsEncrypt CA authority certs into python SSL trusted keys register. See perhaps here https://stackoverflow.com/questions/39356413/how-to-add-a-custom-ca-root-certificate-to-the-ca-store-used-by-python-in-window#39358282. And here. https://stackoverflow.com/questions/34812787/python-ssl-requests-and-lets-encrypt-certs – DisappointedByUnaccountableMod Oct 28 '18 at 09:07
  • Thank you barny, I tried using directly the output of the ca file output of `python -c "import ssl; print(ssl.get_default_verify_paths())"`. Turns out that the `fullchain.pem` certificates generated by certbot are not enough for paho-mqtt and it needs the root certificate from Lets Encrypt. – fedexist Oct 28 '18 at 17:30

1 Answers1

0

certificate has some thing error; Perhaps python make a strict check

when you use openssl s_client, did you unstand all the message which s_client echoed. I have meet some trouble with test ssl communication, finnally, I found the certifacte has wrong time like "not before" or "not after" etc error,

  • Hi, [this is the output](https://pastebin.com/asbn68zs) of the s_client. It looks fine to me, as the SSL handshake completes correctly and the verification gets no error. – fedexist Oct 25 '18 at 09:32
  • you certificate has two depth, you should use "wireshark" check the really pack – wanyuan xiong Oct 25 '18 at 09:43