如何让 paho mqtt 客户端信任 TLS 的自签名证书

问题描述 投票:0回答:1

目前,我正在做一个MQTT测试项目。因此,我设置了一个必须与 TLS 配合使用的 Mosquitto MQTT 代理。问题是,我无法使用安全 TLS 连接通过 PAHO MQTT 客户端建立连接,因为我使用自签名证书。

要启用 TLS,我使用 openssl 并按照以下步骤操作:

  1. 生成假 CA 签名密钥:

    $ openssl genrsa -des3 -out ca.key 2048

  2. 为假CA生成证书签名请求:

    $ openssl req -new -key ca.key -out ca.csr -sha256

  3. 创建假CA的根证书:

    $ openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt -days 365 -sha256

  4. 创建服务器/mqtt代理的密钥对:

    $ openssl genrsa -out server.key 2048

  5. 使用服务器密钥创建证书签名请求,发送给假 CA 进行身份验证:

    $ openssl req -new -key server.key -out server.csr -sha256

    • 我将通用名称设置为我的 Broker 的特定 IP。
  6. 现在作为假CA,我收到了服务器对我的签名请求。我已经验证了服务器的真实身份(在特定 IP 上运行的 MQTT 代理),因此我创建了一个新证书并使用我的虚假权限的所有权力对其进行了签名:

    $ openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 360

创建服务器证书和密钥后,我将这些文件放置在各自的文件夹中,并将 Mosquitto 配置为使用它们来启用 TLS。为此,我修改了

default.conf
:

listener 8883

cafile /etc/mosquitto/ca_certificates/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key

require_certificate true

password_file /etc/mosquitto/passwd

现在我在 paho mqtt 库的帮助下编写了一个 python 脚本来创建一个 mqtt 订阅者客户端。为了启用双向安全连接,我还使用这三个命令为客户端生成了一个证书:

  1. 为客户端创建密钥对:
    openssl genrsa -out client.key 2048
  2. 使用客户端密钥创建证书签名请求,发送给假 CA 进行身份验证:
    openssl req -new -out client.csr -key client.key
  3. 充当假CA:
    openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 360

我的Python代码在paho mqtt库的TLS设置中使用CA证书(ca.crt)、客户端证书(client.crt)和客户端密钥(client.key)。代码如下所示:

import paho.mqtt.client as mqtt
import ssl

def on_message(client, userdata, msg):
    print(f"Received message '{msg.payload.decode()}' on topic '{msg.topic}'")

def on_connect(client, userdata, flags, rc):
    if rc == 0:
        print("Connected to MQTT Broker!")
        client.subscribe("test")
    else:
        print(f"Failed to connect, return code {rc}\n")

client = mqtt.Client()

client.on_connect = on_connect
client.on_message = on_message

username = "x"
password = "x"
client.username_pw_set(username, password)

client.tls_set(ca_certs="certs/ca.crt",
               certfile="certs/client.crt",
               keyfile="certs/client.key",
               tls_version=ssl.PROTOCOL_TLSv1_2)

client.tls_insecure_set(False)  # Ensure this is False for security


broker_address = 'my_ip'  
port = 8883 
client.connect(broker_address, port)

client.loop_forever()

请注意,我在另一台计算机上执行此 python 脚本,并将证书和客户端密钥复制到该计算机。我还通过事先使用不带 TLS 的连接尝试了 MQTT Broker 的一般功能。效果很好。

但是,如果我想执行 python 脚本(使用 TLS)来订阅主题,我会得到以下信息:

mqtt_sub.py:17: DeprecationWarning: Callback API version 1 is deprecated, update to latest version
  client = mqtt.Client()
Traceback (most recent call last):
  File "mqtt_sub.py", line 39, in <module>
    client.connect(broker_address, port)
  File "/home/lutz/.local/lib/python3.8/site-packages/paho/mqtt/client.py", line 1435, in connect
    return self.reconnect()
  File "/home/lutz/.local/lib/python3.8/site-packages/paho/mqtt/client.py", line 1598, in reconnect
    self._sock = self._create_socket()
  File "/home/lutz/.local/lib/python3.8/site-packages/paho/mqtt/client.py", line 4612, in _create_socket
    sock = self._ssl_wrap_socket(sock)
  File "/home/lutz/.local/lib/python3.8/site-packages/paho/mqtt/client.py", line 4671, in _ssl_wrap_socket
    ssl_sock.do_handshake()
  File "/usr/lib/python3.8/ssl.py", line 1338, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1145)

所以我的问题是,如何让 paho mqtt 库使用自签名证书,或者是否可以使用不同的解决方案来实现安全的 mqtt 通信?

ssl mqtt mosquitto paho self-signed
1个回答
0
投票

我按照本指南解决了问题。感谢哈迪尔布的评论!当我用谷歌搜索你的弃用警告时,我找到了指南。

© www.soinside.com 2019 - 2024. All rights reserved.