可以通过 mosquitto 发送 SSL 消息,但从 python paho 脚本获取 CERTIFICATE_VERIFY_FAILED

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

使用蚊子:

mosquitto_pub -h <public ip address> -t testssl/topic -m "hello  world" --cafile ./ca_certificate.pem -p 8883 --tls-version tlsv1.2 -d --id client2

Client client2 sending CONNECT
Client client2 received CONNACK (0)
Client client2 sending PUBLISH (d0, q0, r0, m1, 'testssl/topic', ... (12 bytes))
Client client2 sending DISCONNECT

使用 python paho 脚本:

# python 3.11
import datetime
import json
import random
import time
import uuid

from paho.mqtt import client as mqtt_client

from config import broker, port, topic

# Generate a Client ID with the publish prefix.
client_id = f'publish-{random.randint(0, 100)}'

def connect_mqtt():
    def on_connect(client, userdata, flags, rc):
        if rc == 0:
            print("Connected to MQTT Broker!")
        else:
            print("Failed to connect, return code %d\n", rc)

    client = mqtt_client.Client(client_id)
    client.tls_set(
        ca_certs="ca_certificate.pem",
        tls_version=mqtt_client.ssl.PROTOCOL_TLSv1_2,
    )
    # client.username_pw_set("rw", "readwrite")
    client.on_connect = on_connect
    client.connect(broker, port)
    return client

def fake_sensor_data():
    """Generate a fake sensor data event."""
    list_of_sensor_ids = [ uuid.uuid4() for _ in range(10) ]
    values = [ 0, 0, 0, 0, 0, 0, 1, 0, 0 ]
    return {
        "timestamp": time.time(),
        "device_id": str(list_of_sensor_ids[random.randint(0, 9)]),
        "event": {
            "payload": values[random.randint(0, 8)],
        }
    }



def publish(client):
    while True:
        time.sleep(3)
        msg = json.dumps(fake_sensor_data())
        result = client.publish(topic, msg)
        status = result[0]
        if status == 0:
            print()
            print(datetime.datetime.now(), msg)


def run():
    print("Connecting to MQTT Broker")
    print(f"Broker: {broker}")
    print(f"Port: {port}")
    print(f"Topic: {topic}")
    client = connect_mqtt()
    print("Connected!")
    print("Ready to publish messages!")
    client.loop_start()
    publish(client)
    client.loop_stop()


if __name__ == '__main__':
    run()

错误:

ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: IP address mismatch, certificate is not valid for '<public ip address>'. (_ssl.c:1006)

我在我的服务器上的脚本中使用 tls-gen 生成了 ca_certificate。我在其他地方读到,如果我提供公共 IP 地址而不是 DNS 名称,我应该使用 SAN,但是 tls-gen 不允许我轻松指定一个 - 最好不必修改服务器启动脚本太多了。

我想了解为什么 mosquitto 可以工作,而 python/paho 需要 SAN 来存储相同的证书文件。

python ssl mosquitto paho
1个回答
0
投票

mosquitto验证证书的原因可以在文件中的

mosquitto__verify_certificate_hostname
函数中找到
lib/tls_mosq.c

https://github.com/eclipse/mosquitto/blob/15292b20b0894ec7c5c3d47e4b22ee9d89f91132/lib/tls_mosq.c#L128

可以看到,这是检查

SAN
条目,如果证书中没有
CN
部分,则仅检查
SAN

        if(have_san_dns){
            /* Only check CN if subjectAltName DNS entry does not exist. */
            return 0;
        }`

因此,在没有明确询问 Roger(mosquitto 维护者)的情况下,我希望这只是 mosquitto 仍然支持长期弃用的选项来使用

CN
,而 Python 已经放弃了该选项。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.