配置基于中间CA的Mosquitto MQTT TLS客户端
中间CA场景下Paho MQTT客户端配置TLS连接问题
前置操作说明
证书生成命令
已通过以下OpenSSL命令生成根CA、中间CA及对应签名的服务端/客户端证书:
# 根CA openssl req -new -newkey rsa:4096 -days 365 -extensions v3_ca -subj "/C=CZ/ST=aa/L=bb/O=company/OU=development/CN=ca/" -nodes -x509 -sha256 -set_serial 0 -keyout ca.key -out ca.crt # 中间CA openssl genrsa -out subca.key 4096 openssl req -new -key subca.key -out subca.csr openssl x509 -req -days 365 -in subca.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out subca.crt -extfile openssl.cfg -extensions v3_ca # 服务端证书 openssl req -newkey rsa:4096 -nodes -keyout server.key -subj "/C=CZ/ST=aa/L=bb/O=company/OU=development/CN=server/" -out server.csr openssl x509 -req -extfile <(printf "subjectAltName=IP:177.18.0.1") -days 365 -in server.csr -CA subca.crt -CAkey subca.key -CAcreateserial -out server.crt # 客户端证书 openssl genrsa -des3 -out client.key 4096 openssl req -new -key client.key -subj "/C=CZ/ST=aa/L=bb/O=company/OU=development/CN=client/" -out client.csr openssl x509 -req -in client.csr -CA subca.crt -CAkey subca.key -CAcreateserial -out client.crt -days 365
证书验证
通过以下命令验证服务端/客户端证书有效性:
openssl verify -verbose -CAfile <(cat subca.crt ca.crt) server.crt
Mosquitto服务端配置
已完成Mosquitto服务端TLS配置:
listener 1883 require_certificate false allow_anonymous true listener 8883 capath /mosquitto/config/certs/ca/ certfile /mosquitto/config/certs/server.crt keyfile /mosquitto/config/certs/server.key require_certificate true allow_anonymous true use_identity_as_username true
问题点
配置Paho MQTT客户端时,tls_set()方法的ca_certs参数仅支持单个文件路径,无法直接传入目录或多个证书文件,不清楚如何配置中间CA场景下的信任链。
解决方案
1. 合并信任链证书
将中间CA和根CA的证书合并为一个完整的信任链文件,命令如下:
cat subca.crt ca.crt > ca-chain.pem
注意:合并顺序需与验证时一致,先写入中间CA证书,再写入根CA证书。
2. 修正客户端代码
- 确保
ca_certs指向合并后的信任链文件; - 客户端证书文件需与生成的
client.crt对应(代码中当前写的client.pem需改为client.crt,或把client.crt重命名为client.pem); - 若客户端密钥
client.key使用了-des3设置密码,需在tls_set中添加password参数传入密钥密码,或重新生成不带密码的客户端密钥:openssl genrsa -out client.key 4096
修正后的客户端代码示例:
client = mqtt.Client(client_id='Monitoring Test', clean_session=None, userdata=None, protocol=mqtt.MQTTv5, transport='tcp') client.on_message = on_message # 若client.key有密码,添加password="your_key_password"参数 client.tls_set(ca_certs="ca-chain.pem", certfile="client.crt", keyfile="client.key", tls_version=ssl.PROTOCOL_TLSv1_2) client.connect("177.18.0.1", port=8883, keepalive=60) client.subscribe("topic", qos=2) client.loop_forever(timeout=60)
内容的提问来源于stack exchange,提问作者Zakys98
相关产品推荐
相关产品推荐

