4. 身份与访问管理(IAM)策略调优

身份与访问管理,说白了就是解决两个问题:你是谁,以及你能干什么。在零信任模型下,这两个问题得反复问、持续问,不能因为设备第一次认证通过了就放松警惕。

我早期做物联网平台时,踩过一个坑。当时用的是用户名密码认证,结果某厂商的固件把密码硬编码在二进制里,反编译后全网通用。那之后,我对设备身份认证的态度就变了——必须用证书,必须做到一机一证。

4.1 基于X.509证书的设备身份认证

X.509证书认证,是零信任模型下最推荐的设备身份方案。它解决了三个核心问题:

  • 防伪造:私钥只在设备本地,云端存公钥,中间人无法冒充
  • 防重放:证书链带时间戳和序列号,旧证书被吊销后立即失效
  • 可追溯:每张证书绑定设备唯一标识,审计日志一查一个准

具体到MQTT Broker的配置,我习惯用EMQX或Mosquitto的TLS双向认证。流程是这样的:

  1. 设备烧录时注入设备证书(client.crt)和私钥(client.key)
  2. Broker配置CA证书(ca.crt),只信任由该CA签发的客户端证书
  3. TLS握手时,Broker要求设备出示证书,验证签名和有效期
  4. 验证通过后,从证书的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注册与吊销

设备多了,证书管理就成了大问题。你想想看,十万台设备,每台都要手动生成证书、手动配置?那运维团队得疯掉。

所以我们需要动态注册机制。设备第一次上线时,通过一个预置的“注册凭证”申请正式证书。流程大致如下:

  1. 设备出厂时烧录一个临时的注册证书(有效期极短,比如24小时)
  2. 设备首次连接Broker时,使用注册证书认证,并发送证书签名请求(CSR)
  3. Broker或后端的CA服务验证注册证书有效后,签发正式设备证书
  4. 设备收到正式证书后,断开重连,后续使用正式证书通信

吊销呢?设备被回收、固件被破解、或者证书泄露,都需要立即吊销。我建议用证书吊销列表(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策略架构 设备层 X.509证书 + 私钥 一机一证,不可伪造 传输层 TLS 1.3双向认证 加密通道 + 证书验证 Broker层 EMQX / Mosquitto ACL引擎 + 会话管理 CA服务 / 证书管理 动态注册、签发、吊销 CRL / OCSP Stapling ACL策略引擎 细粒度权限控制 动态更新,实时生效 审计与监控 全链路日志、异常告警、合规报告 核心原则:设备认证 → 传输加密 → 权限控制 → 审计追溯,四层缺一不可 任何一层被绕过,零信任模型就失效了

从这张图你能看到,IAM不是单点功能,而是一条完整的链路。设备带着证书上来,经过TLS验证,Broker根据ACL规则放行,同时后端CA和ACL引擎动态调整策略,所有行为都被审计日志记录下来。

我的建议:别想着一步到位。先搞定证书认证和基础ACL,跑通后再加动态注册和OCSP。我见过太多团队一开始就想搞大而全的IAM平台,结果半年没上线,设备都堆在仓库里吃灰。

最后说一句:零信任模型下的IAM,核心不是技术,而是习惯。你得习惯每次设备连接都做完整认证,习惯最小权限原则,习惯定期审计。这些习惯养成了,安全水平自然就上去了。