Mosquitto MQTT配置TLS/SSL加密后无法收发消息该如何解决?
Mosquitto TLS配置问题修复方案
1. 修复证书权限问题(最常见故障原因)
Mosquitto默认以mosquitto用户运行,而Let's Encrypt生成的证书目录默认只有root用户可读,会导致服务加载证书失败。执行以下操作修复:
- 首先创建Mosquitto专属证书目录:
sudo mkdir /etc/mosquitto/certs - 复制证书到专属目录:
sudo cp /etc/letsencrypt/live/domain.com/{fullchain.pem,privkey.pem,cert.pem} /etc/mosquitto/certs/ - 修改证书属主为Mosquitto用户:
sudo chown -R mosquitto:mosquitto /etc/mosquitto/certs/ - 配置Certbot续期钩子,避免后续证书自动续期后权限失效,在
/etc/letsencrypt/renewal-hooks/post/目录下新建mosquitto.sh文件,写入以下内容:
#!/bin/bash cp /etc/letsencrypt/live/domain.com/{fullchain.pem,privkey.pem,cert.pem} /etc/mosquitto/certs/ chown -R mosquitto:mosquitto /etc/mosquitto/certs/ systemctl restart mosquitto
然后给脚本加执行权限:sudo chmod +x /etc/letsencrypt/renewal-hooks/post/mosquitto.sh
2. 修正Mosquitto配置文件
修改/etc/mosquitto/mosquitto.config为以下内容:
persistence false persistence_location /var/lib/mosquitto/ # 内网明文监听(仅内网使用可保留) listener 1883 192.168.0.235 allow_anonymous false password_file /etc/mosquitto/passwd # 外网TLS加密监听 listener 8883 0.0.0.0 certfile /etc/mosquitto/certs/cert.pem keyfile /etc/mosquitto/certs/privkey.pem # 单向认证无需配置cafile,双向认证时才需要添加 tls_version tlsv1.2 tlsv1.3 require_certificate false allow_anonymous false password_file /etc/mosquitto/passwd log_dest file /var/log/mosquitto/mosquitto.log include_dir /etc/mosquitto/conf.d
修改完成后重启服务生效:sudo systemctl restart mosquitto.service,重启后执行sudo systemctl status mosquitto.service确认服务正常运行。
3. Broker本地测试参数修正
你本地测试时--capath直接使用系统默认CA目录/etc/ssl/certs/即可,Let's Encrypt根证书已默认内置在系统CA列表中。另外你开启了禁止匿名访问,需要加上MQTT账号密码参数才能正常连接,正确的订阅测试命令:mosquitto_sub -h domain.com -t test --capath /etc/ssl/certs/ -u 【你的MQTT用户名】 -P 【你的MQTT密码】 -d -p 8883
4. 远端发布端配置
- 发布端无需拷贝任何服务端证书文件,只要系统CA列表正常即可自动验证服务端证书
- 你之前的发布命令缺少TLS启用参数和账号密码,正确的发布命令:
mosquitto_pub -h domain.com -t test -m "Hello World!" --capath /etc/ssl/certs/ -u 【你的MQTT用户名】 -P 【你的MQTT密码】 -d -p 8883
仅当远端系统为停止维护的极旧版本、未内置Let's Encrypt根证书时,才需要把服务端的fullchain.pem拷贝到远端,用--cafile ./fullchain.pem参数替代--capath /etc/ssl/certs/即可
5. 额外排查点
- 连接失败时优先查看服务日志定位原因:
tail -f /var/log/mosquitto/mosquitto.log - 确认
domain.com已正确解析到你的路由器公网IP - 如果路由器不支持NAT回流,本地用域名访问会失败,可先用内网IP测试8883端口连通性:
mosquitto_sub -h 192.168.0.235 -t test --capath /etc/ssl/certs/ -u 【你的MQTT用户名】 -P 【你的MQTT密码】 -d -p 8883 - 80端口不要关闭,后续Certbot自动续期证书需要使用,443端口如果没有其他Web服务可以关闭,不影响MQTT TLS通信
6. paho-mqtt开发参考
后续用Python paho-mqtt开发时,直接调用默认系统CA即可,示例代码:
import paho.mqtt.client as mqtt client = mqtt.Client() # 配置MQTT账号密码 client.username_pw_set("你的MQTT用户名", "你的MQTT密码") # 启用TLS,不传参数默认使用系统CA列表验证服务端证书 client.tls_set() client.connect("domain.com", 8883, 60)
内容的提问来源于stack exchange,提问作者user8958120
相关产品推荐
相关产品推荐

