发布订阅 ACL

    EMQ X 支持通过客户端发布订阅 ACL 进行客户端权限的管理,本章节介绍了 EMQ X 支持的发布订阅 ACL 以及对应插件的配置方法。

    EMQ X 支持使用配置文件、外部主流数据库和自定义 HTTP API 作为 ACL 数据源。

    连接数据源、进行访问控制功能是通过插件实现的,使用前需要启用相应的插件。

    客户端订阅主题、发布消息时插件通过检查目标主题(Topic)是否在指定数据源允许/禁止列表内来实现对客户端的发布、订阅权限管理。

    配置文件/内置数据源

    使用配置文件提供认证数据源,适用于变动较小的 ACL 管理。

    外部数据库

    外部数据库可以存储大量数据、动态管理 ACL,方便与外部设备管理系统集成。

    HTTP ACL 能够实现复杂的 ACL 管理。

    ACL 功能包含在认证鉴权插件中,更改插件配置后需要重启插件才能生效,

    规则详解

    ACL 是允许与拒绝条件的集合,EMQ X 中使用以下元素描述 ACL 规则:

    同时具有多条 ACL 规则时,EMQ X 将按照规则排序进行合并,以 ACL 文件 中的默认 ACL 为例,ACL 文件中配置了默认的 ACL 规则,规则从下至上加载:

    1. 第二条规则禁止全部客户端订阅 $SYS/## 主题
    2. 第三条规则允许 ip 地址为 127.0.0.1 的客户端发布/订阅 $SYS/## 主题,为第二条开了特例
    3. 第四条规则允许用户名为 dashboard 的客户端订阅 $SYS/# 主题,为第二条开了特例
    1. {allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}.
    2. {allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}.
    3. {deny, all, subscribe, ["$SYS/#", {eq, "#"}]}.
    4. {allow, all}.

    任何一次 ACL 授权最终都会返回一个结果:

    • 允许:经过检查允许客户端进行操作
    • 禁止:经过检查禁止客户端操作
    • 忽略(ignore):未查找到 ACL 权限信息,无法显式判断结果是允许还是禁止,交由下一 ACL 插件或默认 ACL 规则来判断

    全局配置

    默认配置中 ACL 是开放授权的,即授权结果为忽略(ignore)允许客户端通过授权。

    通过 etc/emqx.conf 中的 ACL 配置可以更改该属性:

    配置默认 ,使用文件定义默认 ACL 规则:

    1. # etc/emqx.conf

    在 MQTT v3.1 和 v3.1.1 协议中,发布操作被拒绝后服务器无任何报文错误返回,这是协议设计的一个缺陷。但在 MQTT v5.0 协议上已经支持应答一个相应的错误报文。

    客户端可拥有“超级用户”身份,超级用户拥有最高权限不受 ACL 限制。

    1. 认证鉴权插件启用超级用户功能后,发布订阅时 EMQ X 将优先检查客户端超级用户身份
    2. 客户端为超级用户时,通过授权并跳过后续 ACL 检查

    ACL 缓存

    ACL 缓存允许客户端在命中某条 ACL 规则后,便将其缓存至内存中,以便下次直接使用,客户端发布、订阅频率较高的情况下开启 ACL 缓存可以提高 ACL 检查性能。

    etc/emqx.conf 可以配置 ACL 缓存大小与缓存时间:

    1. # etc/emqx.conf
    2. ## 是否启用
    3. enable_acl_cache = on
    4. ## 单个客户端最大缓存规则数量
    5. acl_cache_max_size = 32
    6. acl_cache_ttl = 1m

    在更新 ACL 规则后,某些客户端由于已经存在缓存,则无法立即生效。若要立即生效,则需手动清除所有的 ACL 缓存:

    参见 HTTP API - 清除 ACL 缓存

    当同时启用多个 ACL 插件时,EMQ X 将按照插件开启先后顺序进行链式鉴权:

    • 一通过授权,终止链并允许客户端通过验证
    • 一旦授权失败,终止链并禁止客户端通过验证
    • 直到最后一个 ACL 插件仍未通过,根据默认授权配置判定
      • 默认授权为禁止时,禁止客户端通过验证