Mosquitto TLS/SSL 加密配置完全指南
摘要
TLS/SSL 是为 Mosquitto MQTT Broker 提供传输层加密和安全认证的核心技术。本文从 TLS 的基本原理出发,系统性地介绍证书体系、生成步骤、配置方法、客户端集成以及运维管理,帮助读者在生产环境中部署安全的 MQTT 加密通信。
第一部分:TLS 概述
1.1 什么是 TLS
TLS(Transport Layer Security,传输层安全协议)是 SSL(Secure Sockets Layer)的继任者,为网络通信提供加密、认证和数据完整性保护。
在 Mosquitto 中,TLS 可以实现:
| 功能 | 说明 |
|---|---|
| 传输加密 | 所有 MQTT 消息加密传输,防止网络窃听 |
| 服务器身份认证 | 客户端验证 Broker 是否可信(防止中间人攻击) |
| 客户端身份认证 | 可选的双向 TLS,Broker 验证客户端身份 |
1.2 为什么需要 TLS

1.3 密码认证 vs TLS 加密
| 对比维度 | 密码认证 | TLS 加密 |
|---|---|---|
| 作用 | 验证客户端身份(你是谁) | 加密传输内容(防窃听) |
| 解决什么问题 | 防止非法设备接入 | 防止密码被截获、消息泄露 |
| 是否加密数据 | ❌ 不加密 | ✅ 全链路加密 |
| 能否单独使用 | ✅ 可以(但不安全) | ⚠️ 可以(但无法认证身份) |
| 标准端口 | 1883(明文) | 8883(加密) |
结论:密码认证 + TLS 加密 = 既验证身份,又加密传输。生产环境必须同时使用。
第二部分:证书体系
2.1 证书信任链
TLS 依赖一套证书信任链来建立信任关系:

2.2 证书文件说明
| 文件 | 用途 | 权限 | 持有方 |
|---|---|---|---|
ca.crt | CA 根证书,验证服务器身份 | 644 | Broker + 所有客户端 |
ca.key | CA 私钥,签发证书用 | 600 | 仅证书管理员(Broker 不需要) |
server.crt | 服务器证书,证明 Broker 身份 | 644 | Broker |
server.key | 服务器私钥,TLS 握手用 | 600 | Broker |
client.crt | 客户端证书(双向 TLS) | 644 | 客户端 |
client.key | 客户端私钥(双向 TLS) | 600 | 客户端 |
2.3 TLS 模式对比
| 模式 | 服务器提供证书 | 客户端提供证书 | 适用场景 |
|---|---|---|---|
| 无 TLS | ❌ | ❌ | 内网测试(不安全) |
| 单向 TLS | ✅ | ❌ | 公网部署,客户端只需验证服务器 |
| 双向 TLS (mTLS) | ✅ | ✅ | 高安全环境,服务器也验证客户端 |
第三部分:证书生成
3.1 生成 CA 根证书
# 创建证书目录
sudo mkdir -p /etc/mosquitto/certs
cd /etc/mosquitto/certs
# 生成 CA 私钥
sudo openssl genrsa -out ca.key 2048
# 生成 CA 根证书(有效期 10 年)
sudo openssl req -new -x509 -days 3650 -key ca.key -out ca.crt \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=MQTT-CA"
# 查看证书内容
openssl x509 -in ca.crt -text -noout
参数说明:
| 参数 | 含义 | 说明 |
|---|---|---|
genrsa | 生成 RSA 私钥 | 非对称加密算法 |
-out | 输出文件 | 指定私钥文件路径 |
2048 | 密钥长度 | 安全要求至少 2048 位 |
req | 证书请求工具 | 创建证书签名请求或自签名证书 |
-new | 新建证书 | 生成新证书 |
-x509 | 自签名证书 | 输出根证书(不是 CSR) |
-days | 有效期 | 单位:天 |
-key | 使用的私钥 | 指定私钥文件 |
-subj | 证书主体信息 | 见下方详解 |
-subj 参数详解:
/C=CN Country(国家) → 2位字母
/ST=Beijing State/Province(省份) → 省/州
/L=Beijing Locality(城市) → 城市
/O=MyCompany Organization(组织) → 公司名
/CN=MQTT-CA Common Name(通用名称) → 唯一标识(CA 名称)
3.2 生成服务器证书
# 生成服务器私钥
sudo openssl genrsa -out server.key 2048
# 生成证书签名请求
sudo openssl req -new -key server.key -out server.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=mqtt.example.com"
# 使用 CA 签发服务器证书
sudo openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt -days 365
# 设置权限
sudo chmod 600 server.key
关键点:
CN 字段必须填写 Broker 的域名或 IP 地址
- 使用域名:
/CN=mqtt.example.com- 使用 IP:
/CN=192.168.1.10
如果 CN 不匹配,客户端连接会报证书验证失败。
3.3 生成客户端证书(双向 TLS)
# 生成客户端私钥
sudo openssl genrsa -out client.key 2048
# 生成客户端证书签名请求
sudo openssl req -new -key client.key -out client.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=device_001"
# 使用 CA 签发客户端证书
sudo openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out client.crt -days 365
# 设置权限
sudo chmod 600 client.key
3.4 生成脚本(一键生成所有证书)
#!/bin/bash
# generate-certs.sh - 一键生成所有证书
set -e
CERT_DIR="/etc/mosquitto/certs"
SERVER_CN="mqtt.example.com" # 修改为你的域名或 IP
echo "=== 开始生成 TLS 证书 ==="
# 创建目录
sudo mkdir -p $CERT_DIR
cd $CERT_DIR
# 1. 生成 CA
echo "1. 生成 CA 根证书..."
sudo openssl genrsa -out ca.key 2048
sudo openssl req -new -x509 -days 3650 -key ca.key -out ca.crt \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=MQTT-CA"
# 2. 生成服务器证书
echo "2. 生成服务器证书 (CN=$SERVER_CN)..."
sudo openssl genrsa -out server.key 2048
sudo openssl req -new -key server.key -out server.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=$SERVER_CN"
sudo openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt -days 365
# 3. 设置权限
echo "3. 设置权限..."
sudo chmod 600 ca.key server.key
sudo chown -R mosquitto:mosquitto $CERT_DIR
echo "✅ 证书生成完成!"
echo "📁 证书目录: $CERT_DIR"
echo "📋 文件清单:"
ls -la $CERT_DIR
第四部分:Mosquitto TLS 配置
4.1 单向 TLS 配置
sudo tee /etc/mosquitto/conf.d/tls.conf << 'EOF'
# ================================================================
# TLS/SSL 加密配置(单向 TLS)
# ================================================================
# TLS 加密监听端口
listener 8883 0.0.0.0
# 服务器证书和私钥
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
# CA 证书(客户端用它验证服务器)
cafile /etc/mosquitto/certs/ca.crt
# TLS 版本(推荐 tlsv1.2 或 tlsv1.3)
tls_version tlsv1.2
# 加密套件(推荐安全套件)
ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256
EOF
4.2 双向 TLS 配置(mTLS)
sudo tee /etc/mosquitto/conf.d/tls-mtls.conf << 'EOF'
# ================================================================
# TLS/SSL 加密配置(双向 TLS)
# ================================================================
listener 8883 0.0.0.0
# 服务器证书
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
cafile /etc/mosquitto/certs/ca.crt
# 强制客户端提供证书
require_certificate true
# 使用证书 CN 作为用户名(简化 ACL 配置)
use_identity_as_username true
tls_version tlsv1.2
EOF
4.3 完整安全配置(密码 + TLS + ACL)
sudo tee /etc/mosquitto/conf.d/security.conf << 'EOF'
# ================================================================
# 完整安全配置
# ================================================================
# ---------- 监听器 ----------
listener 1883 192.168.1.10 # 内网明文(仅内网访问)
listener 8883 0.0.0.0 # 公网 TLS
# ---------- TLS ----------
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
cafile /etc/mosquitto/certs/ca.crt
tls_version tlsv1.2
# ---------- 认证 ----------
allow_anonymous false
password_file /etc/mosquitto/passwd
# ---------- 授权 ----------
acl_file /etc/mosquitto/aclfile
EOF
第五部分:客户端 TLS 连接
5.1 命令行客户端
单向 TLS
# 订阅
mosquitto_sub -h mqtt.example.com -p 8883 \
-t "test" \
--cafile /etc/mosquitto/certs/ca.crt \
-u admin -P 密码 -v
# 发布
mosquitto_pub -h mqtt.example.com -p 8883 \
-t "test" -m "hello" \
--cafile /etc/mosquitto/certs/ca.crt \
-u admin -P 密码
双向 TLS
# 双向 TLS 连接
mosquitto_sub -h mqtt.example.com -p 8883 \
-t "devices/device_001/command/+" \
--cafile /etc/mosquitto/certs/ca.crt \
--cert /etc/mosquitto/certs/client.crt \
--key /etc/mosquitto/certs/client.key \
-v
5.2 Python (paho-mqtt)
import paho.mqtt.client as mqtt
# ================================================================
# 单向 TLS
# ================================================================
client = mqtt.Client()
client.tls_set(
ca_certs="/path/to/ca.crt", # CA 证书(必需)
cert_reqs=mqtt.ssl.CERT_REQUIRED, # 要求服务器提供证书
tls_version=mqtt.ssl.PROTOCOL_TLSv1_2
)
client.username_pw_set("sensor_001", "password")
client.connect("mqtt.example.com", 8883, 60)
client.loop_forever()
# ================================================================
# 双向 TLS
# ================================================================
client.tls_set(
ca_certs="/path/to/ca.crt",
certfile="/path/to/client.crt", # 客户端证书
keyfile="/path/to/client.key", # 客户端私钥
cert_reqs=mqtt.ssl.CERT_REQUIRED,
tls_version=mqtt.ssl.PROTOCOL_TLSv1_2
)
5.3 Node.js (mqtt.js)
const mqtt = require('mqtt')
const fs = require('fs')
// 单向 TLS
const client = mqtt.connect('mqtts://mqtt.example.com:8883', {
ca: fs.readFileSync('/path/to/ca.crt'),
username: 'sensor_001',
password: 'password',
rejectUnauthorized: true,
protocol: 'mqtts'
})
// 双向 TLS
const client2 = mqtt.connect('mqtts://mqtt.example.com:8883', {
ca: fs.readFileSync('/path/to/ca.crt'),
cert: fs.readFileSync('/path/to/client.crt'),
key: fs.readFileSync('/path/to/client.key'),
username: 'sensor_001',
password: 'password',
rejectUnauthorized: true,
protocol: 'mqtts'
})
5.4 证书在项目中的存放
项目目录/
├── certs/
│ ├── ca.crt # CA 证书(所有客户端都需要)
│ ├── client_001.crt # 每个客户端独立证书
│ ├── client_001.key # 客户端私钥(需严格保密)
│ └── client_002.crt
│ └── client_002.key
├── src/
│ ├── main.py
│ └── ...
└── config/
└── config.json # 配置中引用证书路径
// config.json
{
"mqtt": {
"broker": "mqtt.example.com",
"port": 8883,
"tls": {
"ca_cert": "certs/ca.crt",
"client_cert": "certs/client_001.crt",
"client_key": "certs/client_001.key"
},
"username": "sensor_001",
"password": "password"
}
}
第六部分:运维管理
6.1 证书有效期管理
# 查看证书有效期
openssl x509 -in /etc/mosquitto/certs/server.crt -noout -dates
# 输出示例:
# notBefore=Jan 15 00:00:00 2024 GMT
# notAfter=Jan 15 00:00:00 2025 GMT
6.2 证书续期检查脚本
#!/bin/bash
# check-cert-expiry.sh - 检查证书过期时间
DAYS_WARNING=30
CERT_DIR="/etc/mosquitto/certs"
echo "=== 证书有效期检查 ==="
for cert in $CERT_DIR/*.crt; do
if [ -f "$cert" ]; then
END_DATE=$(openssl x509 -in "$cert" -noout -enddate | cut -d= -f2)
END_EPOCH=$(date -d "$END_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($END_EPOCH - $NOW_EPOCH) / 86400 ))
if [ $DAYS_LEFT -lt 0 ]; then
echo "❌ $cert 已过期!"
elif [ $DAYS_LEFT -lt $DAYS_WARNING ]; then
echo "⚠️ $cert 将在 $DAYS_LEFT 天后过期"
else
echo "✅ $cert 还有 $DAYS_LEFT 天有效期"
fi
fi
done
6.3 证书续期步骤
# 1. 备份旧证书
sudo cp /etc/mosquitto/certs/server.crt /etc/mosquitto/certs/server.crt.bak
sudo cp /etc/mosquitto/certs/server.key /etc/mosquitto/certs/server.key.bak
# 2. 生成新服务器证书
cd /etc/mosquitto/certs
sudo openssl req -new -key server.key -out server.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=mqtt.example.com"
sudo openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt -days 365
# 3. 重启 Mosquitto
sudo systemctl restart mosquitto
# 4. 验证新证书
openssl x509 -in server.crt -noout -dates
第七部分:故障排除
7.1 常见问题
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
SSL_ERROR | 证书路径错误或权限不足 | 检查文件路径和权限:ls -la /etc/mosquitto/certs/ |
Certificate verify failed | 客户端未信任 CA | 检查 --cafile 是否正确 |
Hostname mismatch | 证书 CN 与域名不匹配 | 重新生成证书,CN 使用正确域名 |
SSL certificate expired | 证书过期 | 重新签发证书 |
Connection refused | 端口未监听或防火墙拦截 | sudo ss -tlnp | grep 8883 |
no CA certificate | 客户端缺少 CA 证书 | 确保 ca.crt 已拷贝到客户端 |
7.2 调试命令
# 1. 检查端口监听
sudo ss -tlnp | grep 8883
# 2. 测试 TLS 连接
openssl s_client -connect mqtt.example.com:8883 -CAfile ca.crt
# 3. 查看证书详情
openssl x509 -in server.crt -text -noout
# 4. 检查 Mosquitto 日志
sudo journalctl -u mosquitto -f
# 5. 前台调试模式
sudo systemctl stop mosquitto
sudo mosquitto -c /etc/mosquitto/mosquitto.conf -v
7.3 防火墙配置
# Ubuntu UFW
sudo ufw allow 8883/tcp
# CentOS/RHEL Firewalld
sudo firewall-cmd --permanent --add-port=8883/tcp
sudo firewall-cmd --reload
第八部分:最佳实践总结
8.1 安全配置检查清单
| 检查项 | 状态 |
|---|---|
密码认证 (allow_anonymous false) | ✅ |
| TLS 加密(端口 8883) | ✅ |
| 私钥权限 600 | ✅ |
| 证书有效期 < 365 天 | ✅ |
| 使用安全 TLS 版本(1.2 或 1.3) | ✅ |
| 使用安全加密套件 | ✅ |
| 客户端验证服务器证书 | ✅ |
| 定期检查证书有效期 | ⚠️ 需计划 |
8.2 环境区分建议
| 环境 | TLS 配置 | 密码认证 |
|---|---|---|
| 开发测试 | 自签名证书,单向 TLS | 允许匿名或弱密码 |
| 预发布 | 自签名或正式证书 | 强密码 |
| 生产环境 | 正式 CA 签发证书 | 强密码 + 双向 TLS |
8.3 证书管理原则
| 原则 | 说明 |
|---|---|
| 私钥保密 | *.key 文件绝对不要上传到代码仓库 |
| 定期续期 | 设置日历提醒,证书有效期通常 1 年 |
| 最小权限 | 私钥文件仅 mosquitto 用户可读 |
| 审计日志 | 记录证书签发和使用情况 |
结语
TLS 是 Mosquitto 公网部署的安全基石。它解决了明文传输的所有安全问题:
- 加密:保护消息内容不被窃听
- 认证:确保客户端连接到正确的服务器
- 完整性:防止消息在传输过程中被篡改
核心要点速记:
| 要点 | 命令/配置 |
|---|---|
| 生成 CA | openssl req -new -x509 -key ca.key -out ca.crt |
| 签发服务器证书 | openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key |
| Mosquitto 配置 | listener 8883 + certfile + keyfile |
| 客户端连接 | --cafile ca.crt |
| 检查证书 | openssl x509 -in server.crt -noout -dates |