4. 身份与访问管理(IAM)策略调优
身份与访问管理,说白了就是解决两个问题:你是谁,以及你能干什么。在零信任模型下,这两个问题得反复问、持续问,不能因为设备第一次认证通过了就放松警惕。
我早期做物联网平台时,踩过一个坑。当时用的是用户名密码认证,结果某厂商的固件把密码硬编码在二进制里,反编译后全网通用。那之后,我对设备身份认证的态度就变了——必须用证书,必须做到一机一证。
4.1 基于X.509证书的设备身份认证
X.509证书认证,是零信任模型下最推荐的设备身份方案。它解决了三个核心问题:
- 防伪造:私钥只在设备本地,云端存公钥,中间人无法冒充
- 防重放:证书链带时间戳和序列号,旧证书被吊销后立即失效
- 可追溯:每张证书绑定设备唯一标识,审计日志一查一个准
具体到MQTT Broker的配置,我习惯用EMQX或Mosquitto的TLS双向认证。流程是这样的:
- 设备烧录时注入设备证书(client.crt)和私钥(client.key)
- Broker配置CA证书(ca.crt),只信任由该CA签发的客户端证书
- TLS握手时,Broker要求设备出示证书,验证签名和有效期
- 验证通过后,从证书的Common Name(CN)或Subject Alternative Name(SAN)中提取设备ID
关键配置示例(EMQX 5.x)
listeners.ssl.default {
bind = "0.0.0.0:8883"
ssl_options {
cacertfile = "/etc/emqx/certs/ca.crt"
certfile = "/etc/emqx/certs/server.crt"
keyfile = "/etc/emqx/certs/server.key"
verify = "verify_peer"
fail_if_no_peer_cert = true
}
}
我的经验:fail_if_no_peer_cert一定要设为true。我曾经见过一个项目,这参数没开,结果设备没带证书也能连上来,Broker直接给了匿名会话。那等于认证白做了。
4.2 动态客户端ID注册与吊销
设备多了,证书管理就成了大问题。你想想看,十万台设备,每台都要手动生成证书、手动配置?那运维团队得疯掉。
所以我们需要动态注册机制。设备第一次上线时,通过一个预置的“注册凭证”申请正式证书。流程大致如下:
- 设备出厂时烧录一个临时的注册证书(有效期极短,比如24小时)
- 设备首次连接Broker时,使用注册证书认证,并发送证书签名请求(CSR)
- Broker或后端的CA服务验证注册证书有效后,签发正式设备证书
- 设备收到正式证书后,断开重连,后续使用正式证书通信
吊销呢?设备被回收、固件被破解、或者证书泄露,都需要立即吊销。我建议用证书吊销列表(CRL)或在线证书状态协议(OCSP)。
| 方案 | 实时性 | 网络开销 | 适用场景 |
|---|---|---|---|
| CRL | 低(有更新延迟) | 低(定期拉取) | 离线设备、低功耗设备 |
| OCSP | 高(实时查询) | 高(每次连接都查) | 在线设备、高安全要求 |
| OCSP Stapling | 高(Broker缓存) | 中(Broker代查) | 大规模部署、性能敏感 |
避坑指南:我曾经在一个项目中只用CRL,更新周期设成了7天。结果有一批设备证书泄露,黑客拿着证书玩了整整一周才被吊销。后来我改成OCSP Stapling,Broker每小时刷新一次缓存,吊销延迟控制在分钟级。
4.3 细粒度ACL(访问控制列表)设计
认证通过后,设备能干什么?这就是ACL的活了。零信任模型下,ACL必须做到最小权限——设备只能访问它必须用到的主题,其他一律拒绝。
我见过最糟糕的设计:所有设备都允许发布和订阅#。那等于把整个MQTT集群的门都敞开了。设备A发一条假数据到设备B的主题,设备B直接误动作。这种事故,我处理过不止一次。
细粒度ACL的设计原则:
- 基于设备类型分组:传感器只能发布
/sensors/<设备ID>/data,不能订阅其他设备的数据 - 基于主题模式匹配:使用MQTT通配符
+和#,但要严格控制范围 - 发布与订阅分离:有些设备只能发布,有些只能订阅,不能混用
- 动态ACL:设备状态变化时(如被禁用),ACL立即生效,不需要重启Broker
EMQX ACL配置示例(基于文件)
# 允许设备 sensor_001 发布自己的数据
{allow, {user, "sensor_001"}, publish, ["/sensors/sensor_001/data"]}.
# 允许所有传感器订阅告警主题
{allow, {username, {re, "^sensor_"}}, subscribe, ["/alerts/#"]}.
# 拒绝所有其他操作
{deny, all, publish, ["#"]}.
{deny, all, subscribe, ["#"]}.
嗯,这里要注意:ACL的顺序很重要。EMQX和Mosquitto都是第一条匹配即生效。所以deny all一定要放在最后,否则前面的allow规则全被覆盖了。
4.4 整体IAM策略架构
把上面三块串起来,就是一套完整的IAM策略。我画了一张图,帮你理清关系:
从这张图你能看到,IAM不是单点功能,而是一条完整的链路。设备带着证书上来,经过TLS验证,Broker根据ACL规则放行,同时后端CA和ACL引擎动态调整策略,所有行为都被审计日志记录下来。
我的建议:别想着一步到位。先搞定证书认证和基础ACL,跑通后再加动态注册和OCSP。我见过太多团队一开始就想搞大而全的IAM平台,结果半年没上线,设备都堆在仓库里吃灰。
最后说一句:零信任模型下的IAM,核心不是技术,而是习惯。你得习惯每次设备连接都做完整认证,习惯最小权限原则,习惯定期审计。这些习惯养成了,安全水平自然就上去了。