3. Mosquitto部署与配置:单节点部署、配置文件详解、TLS/SSL加密、认证与授权、WebSocket支持
好,咱们进入正题。这一章我打算把 Mosquitto 的部署和配置彻底讲透。你想想看,消息队列能不能跑得稳,MQTT Broker 这一层是关键中的关键。我自己在多个物联网项目里都用 Mosquitto,轻量、稳定、社区活跃,说实话,中小规模的边缘场景它几乎是最优解。
3.1 单节点部署:别想复杂了,其实就三步
单节点部署,说白了就是在一台边缘设备上把 Mosquitto 跑起来。我个人习惯用 Docker,但如果你在资源受限的 ARM 板子上,直接 apt 安装更省事。
方式一:apt 安装(推荐嵌入式场景)
sudo apt update
sudo apt install mosquitto mosquitto-clients -y
sudo systemctl start mosquitto
sudo systemctl enable mosquitto
装完以后,你试试能不能连上:
mosquitto_sub -h localhost -t "test" -v
再开一个终端:
mosquitto_pub -h localhost -t "test" -m "Hello Edge"
能收到消息,说明部署成功了。嗯,这里要注意,默认配置下 Mosquitto 是允许匿名连接的,生产环境千万别这么干。
方式二:Docker 部署(适合快速迭代)
docker run -d --name mosquitto \
-p 1883:1883 \
-p 9001:9001 \
-v /mosquitto/config:/mosquitto/config \
-v /mosquitto/data:/mosquitto/data \
-v /mosquitto/log:/mosquitto/log \
eclipse-mosquitto:2.0.18
我在项目中遇到过一个问题:Docker 部署时如果挂载目录权限不对,Mosquitto 会直接拒绝启动。解决办法很简单,给目录 777 权限,或者把容器内的 mosquitto 用户 UID(通常是 1883)映射到宿主机。
3.2 配置文件详解:别被吓到,核心参数就这几个
Mosquitto 的配置文件默认在 /etc/mosquitto/mosquitto.conf。我第一次看这个文件时也觉得眼花缭乱,但后来发现,真正需要你动手改的,其实就下面这些。
| 参数 | 默认值 | 说明 |
|---|---|---|
listener 1883 |
1883 | MQTT 标准端口,明文传输 |
listener 8883 |
无 | TLS/SSL 加密端口,需要证书 |
listener 9001 |
无 | WebSocket 端口,用于浏览器连接 |
allow_anonymous |
true | 是否允许匿名连接,生产环境必须 false |
password_file |
无 | 用户名密码认证文件路径 |
acl_file |
无 | 访问控制列表文件路径 |
一个典型的生产环境配置长这样:
# 监听端口
listener 1883
listener 8883
listener 9001
# 协议类型
protocol mqtt
protocol websockets
# 安全配置
allow_anonymous false
password_file /etc/mosquitto/passwd
acl_file /etc/mosquitto/acl
# TLS 配置
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
tls_version tlsv1.2
# 日志配置
log_dest file /var/log/mosquitto/mosquitto.log
log_type all
connection_messages true
log_timestamp true
你可能会问,为什么要把 1883、8883、9001 都打开?我的经验是:内网设备用 1883 明文通信(速度快),公网设备走 8883 加密,Web 管理界面用 9001 的 WebSocket。各司其职,互不干扰。
listener 1883 是对的,listener 1883 0.0.0.0 在某些版本里会报错。我曾经因为这个排查了半小时,最后发现是格式问题。
3.3 TLS/SSL 加密:给数据穿上防弹衣
边缘设备经常部署在不受控的物理环境中,Wi-Fi 可能被嗅探,网线可能被监听。TLS 加密不是可选项,是必选项。
生成自签名证书(测试环境够用)
# 1. 创建 CA 证书
openssl req -new -x509 -days 365 -extensions v3_ca \
-keyout ca.key -out ca.crt
# 2. 生成服务器私钥和证书请求
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr
# 3. 用 CA 签发服务器证书
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt -days 365
然后把三个文件放到 /etc/mosquitto/certs/ 目录下,配置里引用即可。客户端连接时需要指定 CA 证书:
mosquitto_sub -h your-edge-device.com -p 8883 \
--cafile /path/to/ca.crt \
-t "secure/topic" -v
我记得有一次在现场调试,客户端一直报证书验证失败。查了半天,发现是服务器证书的 Common Name 填的是 IP 地址,而客户端连接时用的是域名。OpenSSL 默认会做 CN 匹配,对不上就报错。后来我改用 Subject Alternative Name(SAN)才解决。
3.4 认证与授权:谁可以做什么,必须说清楚
匿名连接是魔鬼。我见过太多项目上线后才发现任何人都能订阅所有主题,那画面太美我不敢看。
第一步:创建用户
sudo mosquitto_passwd -c /etc/mosquitto/passwd admin
# 输入密码两次
sudo mosquitto_passwd /etc/mosquitto/passwd sensor01
-c 参数会创建新文件,后续添加用户时不要加 -c,否则会覆盖已有用户。
第二步:配置 ACL(访问控制)
ACL 文件 /etc/mosquitto/acl 的内容示例:
# 所有用户可读系统主题
topic read $SYS/#
# admin 用户拥有全部权限
user admin
topic readwrite #
# sensor01 只能发布传感器数据
user sensor01
topic write sensor/+/data
# 匿名用户只能读取公共状态
topic read public/status
ACL 的匹配规则是从上到下,第一条匹配到的规则生效。所以把最宽松的规则放在最后,最严格的放在前面。
sensor/{device_id}/data、actuator/{device_id}/command。这样 ACL 写起来清晰,后期维护也方便。我曾经在一个项目里看到主题名是 a、b、c,那 ACL 简直没法写。
3.5 WebSocket 支持:让浏览器也能玩 MQTT
边缘计算场景里,经常需要在浏览器里查看实时数据。MQTT 原生协议浏览器不支持,但 WebSocket 可以。
配置很简单,在 mosquitto.conf 里加两行:
listener 9001
protocol websockets
如果同时需要 TLS 加密的 WebSocket(即 WSS),再加证书配置:
listener 9001
protocol websockets
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
前端 JavaScript 连接示例:
const client = mqtt.connect('ws://your-edge-device.com:9001', {
username: 'webuser',
password: 'webpass'
});
client.on('connect', function () {
client.subscribe('sensor/+/data', function (err) {
if (!err) {
console.log('订阅成功');
}
});
});
client.on('message', function (topic, message) {
document.getElementById('data').innerHTML = message.toString();
});
这里有个坑:WebSocket 连接时,如果 Mosquitto 开启了 allow_anonymous false,前端必须传用户名密码。而且密码是明文传输的,所以强烈建议 WebSocket 端口也走 TLS。
max_connections 100,防止被恶意连接打爆。
好了,这一章的内容就这些。从单节点部署到 TLS 加密,从用户认证到 WebSocket 支持,每一步都是我在实际项目中踩过坑、填过坑之后总结出来的。下一章咱们聊聊集群部署,那才是真正考验架构能力的地方。