4. 认证与授权:用户名密码认证、客户端证书认证、Token认证(JWT)、ACL访问控制列表配置
说到MQTT的安全,认证与授权这块,我个人的经验是——千万别偷懒。很多项目初期图省事,直接开匿名连接,结果上线后被扫得千疮百孔。今天咱们就把四种主流的认证方式掰开揉碎讲清楚。
核心逻辑:认证是“你是谁”,授权是“你能干什么”。两者缺一不可。
4.1 用户名密码认证
这是最基础的方式,也是我见过用得最多的。说白了,就是客户端连接时带上用户名和密码,Broker 校验一下。
我在项目中遇到过不少团队,直接把密码硬编码在代码里。嗯,这其实很危险。我建议至少做两层防护:
- 传输加密:密码必须走 TLS 加密通道,否则等于明文裸奔
- 密码存储:Broker 端存的是密码哈希值,不是明文
拿 Mosquitto 举例,配置起来很简单:
# mosquitto.conf
allow_anonymous false
password_file /etc/mosquitto/passwd
# 生成密码文件(交互式输入密码)
mosquitto_passwd -c /etc/mosquitto/passwd device001
小技巧:我习惯用 -b 参数批量生成密码,配合脚本做设备出厂预配置,效率高很多。
4.2 客户端证书认证
这种方式安全性更高,但配置也复杂一些。你想想看,每个客户端都有一张独一无二的数字证书,就像身份证一样。
我曾经帮一个工业客户做方案,他们要求设备必须双向认证。当时踩了个坑——证书有效期设了10年,结果发现吊销列表管理起来特别麻烦。后来我建议他们用短期证书(比如90天),配合自动续签机制。
核心流程分三步:
- CA 签发:自建或使用第三方 CA,为每个客户端签发证书
- Broker 配置:开启 require_certificate 选项
- 客户端加载:连接时带上 client.crt 和 client.key
# mosquitto.conf - 证书认证配置
listener 8883
cafile /etc/mosquitto/ca.crt
certfile /etc/mosquitto/server.crt
keyfile /etc/mosquitto/server.key
require_certificate true
use_identity_as_username true
注意:use_identity_as_username true 会把证书的 CN 字段映射为用户名,这样 ACL 可以直接基于证书身份做授权。这个细节很多人不知道。
4.3 Token认证(JWT)
JWT 认证在物联网场景下越来越流行。为什么?因为它无状态、可扩展,特别适合微服务架构。
JWT 的结构其实很简单:Header.Payload.Signature。Payload 里可以携带设备ID、权限范围、过期时间等信息。Broker 只需要验证签名,不需要查数据库。
我记得有一次帮客户做车联网平台,设备量级到了百万级。如果用传统用户名密码认证,每次连接都要查数据库,压力巨大。换成 JWT 后,认证延迟从 200ms 降到了 5ms 以内。
配置示例(以 EMQX 为例):
# emqx.conf
auth.jwt.secret = my_shared_secret_key
auth.jwt.from = password
auth.jwt.verify_claims = on
auth.jwt.verify_claims.username = %u
客户端连接时,把 JWT 放在密码字段里:
# Python 示例
import paho.mqtt.client as mqtt
import jwt
token = jwt.encode({
"device_id": "dev-001",
"exp": 1718000000
}, "my_shared_secret_key", algorithm="HS256")
client = mqtt.Client(client_id="dev-001")
client.username_pw_set("dev-001", token)
client.connect("broker.example.com", 8883)
关键点:JWT 的 secret 一定要保护好。我见过有人把 secret 提交到 GitHub 上,结果被机器人扫到,整个平台被薅羊毛。
4.4 ACL访问控制列表配置
认证通过后,ACL 才是真正决定权限的东西。说白了,就是告诉 Broker:这个设备能发布什么主题、订阅什么主题。
ACL 的配置粒度可以很细。我一般遵循最小权限原则——只给设备它需要的权限,多一个都不给。
Mosquitto 的 ACL 文件格式很直观:
# /etc/mosquitto/acl.conf
# 用户维度
user device001
topic write sensor/temperature
topic read command/device001/#
# 模式匹配
pattern read sensor/%u/#
pattern write command/%u/#
# 匿名用户(如果允许匿名连接)
topic read $SYS/#
ACL 的匹配规则有优先级:
| 规则类型 | 优先级 | 说明 |
|---|---|---|
| 用户规则 | 最高 | 精确匹配用户名 |
| 模式规则 | 中 | 支持 %u(用户名)、%c(客户端ID)变量 |
| 匿名规则 | 最低 | 仅当 allow_anonymous true 时生效 |
避坑指南:我曾经遇到过一个问题——ACL 规则写得太宽泛,导致一个传感器设备能订阅所有其他设备的主题。排查了半天,发现是 pattern 里的通配符写成了 # 而不是 device001/#。所以,ACL 写完后一定要做边界测试。
4.5 四种认证方式对比
最后,我整理了一张对比表,方便你根据场景选择:
| 认证方式 | 安全等级 | 部署复杂度 | 适用场景 |
|---|---|---|---|
| 用户名密码 | 中 | 低 | 小型项目、内部网络 |
| 客户端证书 | 高 | 高 | 工业控制、金融级场景 |
| JWT Token | 高 | 中 | 大规模设备、微服务架构 |
| 组合认证 | 极高 | 高 | 高安全要求、合规场景 |
嗯,认证与授权这块就讲到这里。记住一个原则:认证要严,授权要细。下一层咱们会聊传输加密,那是另一道防线了。