首页 > 解决方案 > Problems using paho mqtt client with python 3.7

问题描述

I am running the following code to connect to a mqtt server.

import paho.mqtt.client as mqtt
import ssl
import uuid

client = mqtt.Client(str(uuid.uuid1()))
client.tls_set(
    "ca.crt",
    "client.crt",
    "client.key",
    cert_reqs=ssl.CERT_REQUIRED,
    tls_version=ssl.PROTOCOL_TLSv1
)
client.connect(
    "127.0.0.1",
    8883,
)
client.loop_forever()

This code works fine with python2.7 version. But when I run it with python3.7 version I am getting the below error.

Traceback (most recent call last):
  File "test.py", line 29, in <module>
    8883,
  File "virtualenvs/mqtt-xG2h6zri/lib/python3.7/site-packages/paho/mqtt/client.py", line 839, in connect
    return self.reconnect()
  File "mqtt-xG2h6zri/lib/python3.7/site-packages/paho/mqtt/client.py", line 994, in reconnect
    sock.do_handshake()
  File ".pyenv/versions/3.7.0/lib/python3.7/ssl.py", line 1108, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: IP address mismatch, certificate is not valid for '127.0.0.1'. (_ssl.c:1045)

Please help me figure out how to make this work in python 3.7.

标签: pythonsslmqttpahopython-3.7

解决方案


找到了答案。

实际上,根据链接,将服务器 IP 地址与证书的 CN 字段匹配已被弃用超过 15 年。但是低于 3.7 的 python 版本仍然允许这样做,即使它已被弃用。因此,我必须在 SAN 字段中添加服务器的 IP 地址来创建证书。

答案中解释了使用 SAN 字段创建证书。但是答案中的解决方案使用了域名。如果您要使用 IP 地址创建证书,请使用此命令创建证书,而不是该答案中的命令。

openssl x509 -req -in server.csr \
        -extfile <(printf "subjectAltName=IP:127.0.0.1") \
        -CA ca.crt \
        -CAkey ca.key \
        -CAcreateserial -out server.crt \
        -days 365

使用这些证书后,错误就解决了。


推荐阅读