蚊子MQTT:将“ca_certs”设置为“/etc/ssl/certs/”会导致“IsA目录错误:[Errno 21]是一个目录'

nnt7mjpx  于 2023-02-19  发布在  其他
关注(0)|答案(1)|浏览(106)

我正在寻找相应的代码

# this works fine!
mosquitto_sub --capath /etc/ssl/certs/ -u user -P xyz -h hostname.com -p 8883 -t '#'

这是我的代码,应该做同样的事情...

import ssl
import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))
    client.subscribe("#")

def on_message(client, userdata, msg):
    print(msg.topic + " " + str(msg.payload))

client = mqtt.Client()
client.username_pw_set("user", "xyz ")
client.tls_set("/etc/ssl/certs/", tls_version=ssl.PROTOCOL_TLSv1_2) # <- line 16

client.on_connect = on_connect
client.on_message = on_message
client.connect("hostname.com", 8883)

client.loop_forever()

但它给了我一个例外

Traceback (most recent call last):
  File "/workspaces/mqtt.py", line 16, in <module>
    client.tls_set("/etc/ssl/certs/", tls_version=ssl.PROTOCOL_TLSv1_2)
  File "/home/vscode/.local/lib/python3.9/site-packages/paho/mqtt/client.py", line 804, in tls_set
    context.load_verify_locations(ca_certs)
IsADirectoryError: [Errno 21] Is a directory

我不明白为什么,正如the documentation所说:* 证书颁发机构证书文件的字符串路径 *

m1m5dgzv

m1m5dgzv1#

查看实际的代码,它似乎需要一个指向单个文件的路径,该文件将所有cacert连接在一起。
https://github.com/eclipse/paho.mqtt.python/blob/a4cb435ca2864d073ea3e0e18b0407e4bbe85b16/src/paho/mqtt/client.py#L804

if ca_certs is not None:
            context.load_verify_locations(ca_certs)
        else:
            context.load_default_certs()

这只是将ca_certs参数直接传递给context.load_verify_locations(),文档暗示context.load_verify_locations()可以接受3个命名参数中的任何一个。

SSL上下文.加载验证位置(文件=无,容量=无,数据=无)

当verify_mode不是CERT_NONE时,加载一组用于验证其他对等方证书的“证书颁发机构”(CA)证书。必须至少指定cafile或capath之一。
此方法还可以PEM或DER格式加载证书吊销列表(CRL)。为了使用CRL,必须正确配置SSLContext.verify_flags。

  • cafile* 字符串(如果存在)是PEM格式的串联CA证书文件的路径。有关如何在此文件中排列证书的详细信息,请参阅证书的讨论。
  • capath* 字符串(如果存在)是包含多个PEM格式CA证书的目录的路径,遵循OpenSSL特定布局。
  • cadata* 对象(如果存在)是一个或多个PEM编码证书的ASCII字符串,或者是DER编码证书的类似字节的对象。与capath一样,PEM编码证书周围的额外行将被忽略,但至少必须存在一个证书。

因为它没有命名参数,所以我假设它被解释为第一个cafile,而不是capath
考虑到您传递的路径通常被认为是默认路径,我猜不传递该参数将导致它调用context.load_default_certs()context.load_default_certs()将加载相同的集。

相关问题