3. Mosquitto进阶配置:监听器配置、认证与授权、TLS/SSL加密、WebSocket支持
好,咱们接着往下聊。上一章我们把Mosquitto跑起来了,能发能收,感觉挺爽是吧?但说实话,那只是皮毛。生产环境里,你不可能裸奔着让客户端随便连。这一章,咱们来点硬核的——监听器、认证授权、TLS加密,还有WebSocket支持。这些都是我实际项目中天天打交道的东西,踩过的坑也不少,今天一并倒给你。
3.1 监听器配置:不止一个端口那么简单
Mosquitto默认监听1883端口,这是MQTT的明文端口。但实际场景中,你可能需要多个监听器——比如一个给内网设备用(明文),一个给外网用(加密),甚至再来一个给WebSocket用。
我个人习惯把监听器配置写在配置文件最前面,清晰明了。来看个例子:
# 监听1883端口,明文,绑定内网IP
listener 1883 192.168.1.100
protocol mqtt
# 监听8883端口,TLS加密,绑定公网IP
listener 8883 0.0.0.0
protocol mqtt
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
# 监听8083端口,WebSocket支持
listener 8083 0.0.0.0
protocol websockets
每个listener后面跟端口和IP地址。IP可以省略,默认监听所有接口。但我在项目中遇到过一个问题——如果你不指定IP,Mosquitto会监听所有网卡,包括Docker的虚拟网卡,有时候会引发奇怪的路由问题。所以,我建议你养成习惯,显式指定IP。
listener 1883 0.0.0.0监听所有,但最好还是明确绑定到业务网卡上。我曾经因为没指定IP,导致内网设备连到了错误的网卡上,排查了半天。
3.2 认证与授权:别让陌生人进来
默认配置下,Mosquitto允许匿名连接。这在开发环境没问题,但生产环境绝对不行。你想想看,谁都能往你的Broker上发消息,那不乱套了?
Mosquitto支持多种认证方式,最常用的是密码文件和ACL(访问控制列表)。
3.2.1 密码文件认证
先创建密码文件。Mosquitto自带一个工具叫mosquitto_passwd:
# 创建密码文件,添加用户
mosquitto_passwd -c /etc/mosquitto/passwd user1
# 会提示输入密码,输入两次即可
# 添加更多用户(不加-c,否则会覆盖)
mosquitto_passwd /etc/mosquitto/passwd user2
然后在配置文件中启用:
allow_anonymous false
password_file /etc/mosquitto/passwd
这样,客户端连接时必须提供用户名和密码。嗯,这里要注意——密码文件里的密码是经过哈希的,不是明文,所以相对安全。但别以为这样就万事大吉了,明文传输的密码还是会被抓包看到。所以,TLS加密才是王道。
3.2.2 ACL授权:谁可以做什么
认证只是第一步,授权才是关键。ACL文件定义了每个用户能订阅和发布哪些主题。
创建一个ACL文件,比如/etc/mosquitto/acl:
# 允许user1读写所有以sensor/开头的主题
user user1
topic readwrite sensor/#
# 允许user2只读sensor/temperature
user user2
topic read sensor/temperature
# 允许匿名用户读取public/主题
pattern read public/%
然后在配置中引用:
acl_file /etc/mosquitto/acl
ACL的规则是从上到下匹配的,第一条匹配到了就停止。所以,把更具体的规则放在前面,通用的放后面。我在项目中遇到过一个问题——有个用户明明有权限,但就是连不上。后来发现是ACL顺序搞反了,通用规则先匹配到了,直接拒绝了。嗯,这种坑踩一次就记住了。
kill -HUP发送SIGHUP信号重载配置。
3.3 TLS/SSL加密:给数据穿上防弹衣
明文传输的MQTT,说白了就是在裸奔。任何能抓到包的人都能看到你的消息内容。TLS加密就是给数据穿上防弹衣。
3.3.1 生成证书
你需要三样东西:CA证书、服务器证书、服务器私钥。可以用OpenSSL自己生成,也可以用Let's Encrypt这样的免费CA。
自己生成CA和服务器证书的步骤:
# 1. 生成CA私钥和证书
openssl req -new -x509 -days 3650 -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
然后把server.crt和server.key放到Mosquitto的证书目录,比如/etc/mosquitto/certs/。
3.3.2 配置TLS监听器
在配置文件中添加TLS监听器:
listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
tls_version tlsv1.2
这里有个细节——tls_version建议指定为tlsv1.2或更高。TLSv1.0和1.1已经被废弃了,不安全。我见过有些老系统还在用TLSv1.0,说实话,那跟没加密区别不大。
3.3.3 客户端连接
客户端连接TLS端口时,需要指定CA证书来验证服务器身份。以mosquitto_pub为例:
mosquitto_pub -h broker.example.com -p 8883 \
--cafile /path/to/ca.crt \
-t "test/topic" -m "Hello TLS" \
-u user1 -P password
3.4 WebSocket支持:让浏览器也能玩MQTT
传统的MQTT基于TCP,浏览器里没法直接用。但WebSocket可以。Mosquitto从1.4版本开始支持WebSocket,配置起来很简单。
3.4.1 启用WebSocket监听器
在配置文件中添加:
listener 8083
protocol websockets
就这么简单。客户端可以通过WebSocket连接到ws://broker.example.com:8083。
如果你需要WebSocket也走TLS,那就用wss://:
listener 8084
protocol websockets
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
3.4.2 前端连接示例
浏览器端用MQTT.js库连接:
const mqtt = require('mqtt')
const client = mqtt.connect('ws://broker.example.com:8083', {
username: 'user1',
password: 'password'
})
client.on('connect', function () {
console.log('连接成功')
client.subscribe('sensor/#')
})
client.on('message', function (topic, message) {
console.log(topic, message.toString())
})
WebSocket支持让MQTT的应用场景大大扩展了。我在项目中做过一个实时监控大屏,前端直接用WebSocket连Broker,数据延迟不到100毫秒。说实话,效果比轮询好太多了。
3.5 综合配置示例
最后,给你一个完整的配置示例,把上面所有内容整合到一起:
# 基础配置
pid_file /var/run/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
# 明文监听器(内网)
listener 1883 192.168.1.100
protocol mqtt
# TLS监听器(外网)
listener 8883 0.0.0.0
protocol mqtt
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
tls_version tlsv1.2
# WebSocket监听器(明文)
listener 8083 0.0.0.0
protocol websockets
# WebSocket监听器(加密)
listener 8084 0.0.0.0
protocol websockets
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
# 认证与授权
allow_anonymous false
password_file /etc/mosquitto/passwd
acl_file /etc/mosquitto/acl
这个配置基本覆盖了大部分生产场景。你根据实际需求调整IP和端口就行。我个人习惯把不同用途的监听器分开,方便后期排查问题。比如内网设备连1883,外网设备连8883,前端页面连8083或8084。出了问题,看日志就知道是哪个通道的问题。
好了,这一章的内容就到这里。下一章咱们聊聊Mosquitto的集群和高可用部署,那才是真正的大招。到时候我会分享一些我在大规模部署中踩过的坑,保证让你少走弯路。