带有 TLS1.2 连接问题的 Mosquitto 2.0.14 MQTT 客户端 <unknown> 由于格式错误的数据包而断开连接

Mosquitto 2.0.14 MQTT with TLS1.2 connection issues Client <unknown> disconnected due to malformed packet

Mosquitto 2.0.14 Ubuntu 20.04 i9-12900,TLS1.2 连接问题 在我尝试保护它之前,这一切都完美无缺。我在下面添加了有关我如何创建证书、日志、配置文件以及我如何尝试连接的详细信息。如果有人能指出正确的方向,我将不胜感激。

openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt
openssl genrsa -out mosquitto.key 2048
openssl req -new -key mosquitto.key -out mosquitto.csr
openssl x509 -req -in mosquitto.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out mosquitto.crt -days 3650 -sha256
openssl x509 -in ca.crt -out ca.pem //not sure this step was needed

/var/log/mosquitto/mosquitto.log

1643315161: mosquitto version 2.0.14 starting
1643315161: Config loaded from /etc/mosquitto/mosquitto.conf.
1643315161: Opening ipv4 listen socket on port 8883.
1643315161: Opening ipv4 listen socket on port 1883.
1643315161: Opening ipv6 listen socket on port 1883.
1643315161: mosquitto version 2.0.14 running
1643315168: New connection from 192.168.1.99:46526 on port 8883.
1643315168: Client <unknown> disconnected due to malformed packet.
1643315228: New connection from 192.168.1.99:46558 on port 8883.
1643315228: Client <unknown> disconnected due to malformed packet.

/etc/mosquitto/mosquitto.conf

per_listener_settings true
persistence true
persistence_location /var/lib/mosquitto/

log_dest file /var/log/mosquitto/mosquitto.log

include_dir /etc/mosquitto/conf.d

cafile /etc/mosquitto/ca_certificates/ca.pem
keyfile /etc/mosquitto/certs/mosquitto.key
certfile /etc/mosquitto/certs/mosquitto.crt
tls_version tlsv1.2

#default port
listener 8883 192.168.1.99
require_certificate true
allow_anonymous true
protocol mqtt
connection_messages true
log_type debug
log_type error
log_type warning
log_type notice
log_type information

正在尝试这样添加订阅

mosquitto_sub -V mqttv311 -h 192.168.1.99 -p 8883 --cafile /etc/mosquitto/ca_certificates/ca.pem -t sensors/drone01/altitude -d

我创建了一个客户端证书:

openssl x509 -req -in client.csr -CA /etc/mosquitto/ca_certificates/ca.crt -CAkey /etc/mosquitto/ca_certificates/ca.key -CAcreateserial -out client.crt -days 90

订阅:

mosquitto_sub -V mqttv311 -h 192.168.1.99 -p 8883 --cert ./client.crt --key ./client.key -t sensors/drone01/altitude -d 

日志文件中的相同消息: 1643322374: New connection from 192.168.1.99:49000 on port 8883. 1643322374: Client <unknown> disconnected due to malformed packet.

这里是帮助您入门的基本设置。我以与您相同的方式创建了证书(由于其易用性,我通常为此使用 certstrap):

openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt
openssl genrsa -out mosquitto.key 2048
openssl req -new -key mosquitto.key -out mosquitto.csr
openssl x509 -req -in mosquitto.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out mosquitto.crt -days 3650 -sha256

生成 mosquitto.csr 时,我给了它 CN(通用名称)127.0.0.1。基本 mosquitto.conf:

log_type all

# Don't do the below in production (it allows anyone to connect with no auth)
allow_anonymous true

listener 8883
keyfile /path/mosquitto.key
certfile /path/mosquitto.crt

启动 mosquitto 后(我在控制台中使用 mosquitto -c ./mosquitto.conf 执行此操作)然后我 运行:

mosquitto_sub -h 127.0.0.1 -p 8883 --cafile ./ca.crt -t sensors/drone01/altitude -d

本次连接成功:

Client null sending CONNECT
Client null received CONNACK (0)
Client null sending SUBSCRIBE (Mid: 1, Topic: sensors/drone01/altitude, QoS: 0, Options: 0x00)
Client null received SUBACK
Subscribed (mid: 1): 0

这不会使用客户端证书进行身份验证,但会检查服务器名称是否与证书中的 CN 匹配(尝试将 127.0.0.1 更改为 localhost)。如果您的证书没有正确的 CN,您将需要 --insecure 选项)。

现在 TLS 正在运行,让我们添加对客户端证书的要求。从技术上讲,我可以使用与上面相同的证书,但这可能会造成混淆,所以我将生成一个新证书(在生产中我会为此使用不同的 CA):

openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 3650 -sha256

现在我们更新 mosquitto.conf:

log_type all

listener 8883
keyfile /path/mosquitto.key
certfile /path/mosquitto.crt

# We want to require a client certificate
require_certificate true

# This CA is used to verify the client certificate (it need not be the one used for the above mosquitto.crt)
cafile /path/ca.crt

# As we are passing a certificate we can choose to use the certificate CN as out username (removing need for allow_anonymous)
use_identity_as_username true

如果您尝试使用上面使用的 mosquitto_sub 参数进行连接,它现在应该会失败,但以下是有效的(或在我测试时有效):

mosquitto_sub -h 127.0.0.1 -p 8883 --cafile ./ca.crt --cert ./client.crt --key ./client.key -t sensors/drone01/altitude -d