跳转到内容

Mosquitto TLS 配置

Mosquitto TLS 配置

本节介绍如何配置 Mosquitto MQTT Broker 启用 TLS 加密。完成配置后,Broker 将同时支持明文(1883)和加密(8883)两种连接方式。学习完成后,您将能够:

  • 配置 Mosquitto 使用 TLS 证书
  • 配置 Mosquitto 监听 8883 加密端口
  • 配置客户端证书认证(可选)
  • 验证 Broker TLS 配置的正确性

在开始本节之前,请确保:

  • 已获取 Let’s Encrypt 证书
  • 证书文件已复制到 Mosquitto 可访问的目录
  • 了解 Mosquitto 基本配置
  • Mosquitto Broker 已安装并运行
Terminal window
# 如果使用 Docker 运行 Mosquitto
# 1. 创建证书目录
mkdir -p /opt/mosquitto/certs
# 2. 复制证书文件(使用 -L 解析符号链接)
cp -L /etc/letsencrypt/live/mqtt.example.com/fullchain.pem \
/opt/mosquitto/certs/
cp -L /etc/letsencrypt/live/mqtt.example.com/privkey.pem \
/opt/mosquitto/certs/
# 3. 设置权限(Mosquitto 需要读取权限)
chmod 644 /opt/mosquitto/certs/fullchain.pem
chmod 600 /opt/mosquitto/certs/privkey.pem
chown -R 1883:1883 /opt/mosquitto/certs
# 1883 是 Mosquitto Docker 容器内部的用户 ID
Terminal window
# 检查证书内容
openssl x509 -in /opt/mosquitto/certs/fullchain.pem -text -noout
# 检查私钥
openssl rsa -in /opt/mosquitto/certs/privkey.pem -check
# 验证证书和私钥匹配
openssl x509 -noout -modulus -in /opt/mosquitto/certs/fullchain.pem | openssl md5
openssl rsa -noout -modulus -in /opt/mosquitto/certs/privkey.pem | openssl md5
# 两个命令的输出应该相同
/opt/mosquitto/config/mosquitto.conf
# 基本配置
pid_file /mosquitto/data/mosquitto.pid
persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
log_type all
# 明文监听端口(可选,保留用于不支持 TLS 的旧设备)
listener 1883 0.0.0.0
protocol mqtt
# ---- TLS 加密监听端口 ----
listener 8883 0.0.0.0
protocol mqtt
# 证书文件路径
cafile /mosquitto/certs/fullchain.pem # 证书文件(包含中间 CA)
certfile /mosquitto/certs/fullchain.pem # 服务器证书(与 cafile 相同)
keyfile /mosquitto/certs/privkey.pem # 服务器私钥
# TLS 版本要求(推荐 TLS 1.2+)
tls_version tlsv1.2
# 密码套件设置(可选,加强安全性)
# ciphers_tls1.3 TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
# ===== 可选安全加固 =====
# 要求客户端证书(双向 TLS)
# require_certificate true
# 如果启用客户端证书验证,可指定 CA 文件
# cafile /mosquitto/certs/ca.crt
# 吊销列表(可选)
# crlfile /mosquitto/certs/crl.pem
# 证书通用名称验证
# use_identity_as_username true
# ---- 认证配置 ----
# 使用密码文件认证
password_file /mosquitto/config/passwd
# ---- 访问控制 ----
allow_anonymous false
acl_file /mosquitto/config/acl
# ---- 其他配置 ----
max_connections 1000
autosave_interval 900
connection_messages true
docker-compose.yml
version: '3.8'
services:
mosquitto:
image: eclipse-mosquitto:2
container_name: mosquitto
restart: unless-stopped
ports:
- "1883:1883" # MQTT 明文(可选)
- "8883:8883" # MQTT over TLS
- "9001:9001" # WebSocket(可选)
volumes:
- ./config/mosquitto.conf:/mosquitto/config/mosquitto.conf:ro
- ./config/passwd:/mosquitto/config/passwd:ro
- ./config/acl:/mosquitto/config/acl:ro
- ./certs:/mosquitto/certs:ro
- ./data:/mosquitto/data
- ./log:/mosquitto/log
environment:
- TZ=Asia/Shanghai
Terminal window
# 停止并删除旧容器
docker stop mosquitto && docker rm mosquitto
# 重新创建容器
docker-compose up -d mosquitto
# 检查容器状态
docker ps | grep mosquitto
# 查看运行日志
docker logs mosquitto
# 检查 TLS 端口是否监听
docker exec mosquitto netstat -tlnp
# 预期输出:
# tcp 0 0 0.0.0.0:1883 0.0.0.0:* LISTEN -
# tcp 0 0 0.0.0.0:8883 0.0.0.0:* LISTEN -
Terminal window
# 测试 TLS 连接
openssl s_client -connect localhost:8883 \
-CAfile /opt/mosquitto/certs/fullchain.pem \
-servername mqtt.example.com
# 成功输出示例:
# CONNECTED(00000003)
# ---
# Certificate chain
# 0 s:CN = mqtt.example.com
# i:C = US, O = Let's Encrypt, CN = R3
# 1 s:C = US, O = Let's Encrypt, CN = R3
# i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
# ---
# SSL handshake has read 3333 bytes and written 389 bytes
# ---
# New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Terminal window
# 测试加密连接
mosquitto_sub -h mqtt.example.com \
-p 8883 \
--cafile /opt/mosquitto/certs/fullchain.pem \
-t "test/topic" \
-u "testuser" \
-P "testpass" \
-d
# -d 参数输出所有调试信息,包括 TLS 握手细节
# 发布测试消息
mosquitto_pub -h mqtt.example.com \
-p 8883 \
--cafile /opt/mosquitto/certs/fullchain.pem \
-t "test/topic" \
-m "Hello TLS!" \
-u "testuser" \
-P "testpass" \
-d
# 在 mosquitto.conf 中添加
log_type debug
log_type error
log_type warning
log_type notice
log_type information
log_type subscribe
log_type unsubscribe
log_type websockets
log_type all
connection_messages true
Terminal window
# 查看 TLS 相关日志
docker logs mosquitto | grep -i tls
# 输出示例:
# 1726425607: New connection from 192.168.1.50:34567 on port 8883.
# 1726425607: OpenSSL: New TLS connection from 192.168.1.50
# 1726425608: Client esp32_factory_001 connected (TLS1.3, AES-256-GCM)
错误原因解决方案
”connection refused”8883 端口未正确映射检查 Docker 端口映射
”certificate verify failed”证书验证失败确认域名匹配、证书未过期
”permission denied”私钥文件权限不足chmod 600 privkey.pem
”no shared cipher”TLS 版本不兼容配置 tls_version tlsv1.2
”private key mismatch”证书和私钥不匹配从 Let’s Encrypt 重新获取
步骤操作关键点
1获取 Let’s Encrypt 证书需要有效域名
2复制证书文件设置正确权限
3配置 mosquitto.confcafile/certfile/keyfile
4配置 Docker端口映射和 volume 挂载
5重启 Mosquitto检查日志确认启动正常
6测试连接OpenSSL/mosquitto_sub 验证

本节介绍了 Mosquitto TLS 配置:

  1. 证书准备:复制 Let’s Encrypt 证书到 Mosquitto 目录
  2. 配置文件:listener 8883 + cafile/certfile/keyfile 配置
  3. Docker 部署:端口映射和证书 volume 挂载
  4. 验证测试:OpenSSL 和 mosquitto_sub 测试加密连接
  5. 调试日志:开启 debug 日志排查 TLS 连接问题