ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

EMQX Redis 授权兼容模式 v4 深度解析:无缝承接 EMQX 4.x ACL 数据

EMQX Redis 授权兼容模式 v4 深度解析:无缝承接 EMQX 4.x ACL 数据 EMQX Redis 授权兼容模式 v4 深度解析无缝承接 EMQX 4.x ACL 数据【免费下载链接】emqxThe most scalable and reliable MQTT broker for AI, IoT, IIoT and connected vehicles项目地址: https://gitcode.com/gh_mirrors/em/emqxEMQX 5.x 的 Redis 授权Authorization新增了compatibility_mode v4配置项用于兼容 EMQX 4.x 时代写入 Redis 的旧版 ACL 数据。本文以本仓库中对应变更文档 changes/ee/fix-16730.en.md 为核心结合emqx_auth_redis应用的源码实现与测试用例深入讲解该兼容模式的工作原理、配置方法、旧版占位符与 ACL 值的映射规则以及从 EMQX 4.x 平滑迁移到 5.x 的落地要点。读完本文你将能够准确判断是否启用该模式、正确配置 Redis 授权并理解底层占位符渲染与规则解析的完整链路。一、为什么需要兼容模式EMQX 4.x 与 5.x 的 ACL 数据格式差异在 EMQX 4.x 时代Redis 中存储的 ACL访问控制列表数据采用了与 5.x 截然不同的两种约定占位符语法不同4.x 使用%u用户名和%c客户端 ID作为占位符例如查询命令HGETALL mqtt_acl:%u、主题过滤器pub/%u、sub/%c而 5.x 使用${username}、${clientid}这类模板变量语法。访问值编码不同4.x 的规则值使用数字1、2、3分别表示 subscribe订阅、publish发布和 all全部而 5.x 原生接受字符串subscribe、publish、all以及包含action、qos、retain等字段的 JSON 对象。如果直接沿用 4.x 的 Redis 数据5.x 的 Redis 授权会因无法解析这些旧格式而拒绝匹配导致客户端全部被拒或依赖no_match的兜底策略。兼容模式正是为了解决这一迁移痛点而生。二、compatibility_mode 配置项定义、取值与默认行为该配置项在 emqx_authz_redis_schema.erl 中定义属于 Redis 授权数据源的专属字段compatibility_mode() - ?HOCON(hoconsc:enum([disabled, v4]), #{ required false, default disabled, desc ?DESC(compatibility_mode), example v4 }).关键信息如下属性取值说明枚举值disabled/v4仅支持这两个取值默认值disabled默认关闭保证已有 Redis 授权行为完全不变是否必填否不配置即视为disabledi18n 描述文件 emqx_authz_redis_schema.hocon 中给出了官方语义Redis ACL compatibility mode. Set tov4to accept legacy ACL values1|2|3and placeholders%u/%c.配置方式HOCON 格式位于authorization.sources下authorization { sources [ { type redis enable true redis_type single server 127.0.0.1:6379 database 1 password public cmd HGETALL mqtt_acl:%u compatibility_mode v4 } ] }说明测试代码 emqx_authz_redis_SUITE.erl 中的raw_redis_authz_config/0提供了最小可用配置骨架typeredis、redis_typesingle、cmd等可作为手工编写配置时的参照。该配置同样支持redis_sentinel、redis_cluster两种部署形态对应redis_type sentinel / cluster。三、兼容模式下的两大核心行为3.1 旧版占位符 %u/%c 的自动转换启用compatibility_mode v4后cmd命令模板与查询返回的主题过滤器中的%u、%c会被自动转换为 5.x 的模板变量语法${username}、${clientid}。这一逻辑由 emqx_authz_redis.erl 中的normalize_legacy_placeholders/2实现normalize_legacy_placeholders(Bin, ?ACL_COMPAT_MODE_V4) when is_binary(Bin) - binary:replace( binary:replace(Bin, %u, ${username}, [global]), %c, ${clientid}, [global] ); normalize_legacy_placeholders(Value, _ACLCompatibilityMode) - Value.从源码可以看到两个关键细节替换是全局的[global]同一字符串中出现的所有%u/%c都会被替换且先替换%u再替换%c。仅在 v4 模式下生效其他任何取值都原样返回不会做任何转换。该函数被调用在两个位置new_state/2初始化状态时对cmd模板字符串做归一化再进入parse_cmd/1的模板解析流程do_authorize/5中处理每条返回记录时对哈希表的 key即主题过滤器做归一化。也就是说占位符转换同时作用于查询命令和查询结果中的主题过滤器。例如 4.x 的HGETALL mqtt_acl:%u在 v4 模式下等效于 5.x 的HGETALL mqtt_acl:${username}而存储为pub/%u的主题过滤器会被当作pub/${username}参与匹配。3.2 旧版 ACL 访问值 1|2|3 的映射启用 v4 模式后查询结果中的规则值1、2、3会被映射为订阅、发布、全部三种动作。该逻辑位于parse_rule/2parse_rule(1, ?ACL_COMPAT_MODE_V4) - {ok, #{action subscribe}}; parse_rule(2, ?ACL_COMPAT_MODE_V4) - {ok, #{action publish}}; parse_rule(3, ?ACL_COMPAT_MODE_V4) - {ok, #{action all}}; parse_rule(publish, _ACLCompatibilityMode) - {ok, #{action publish}}; parse_rule(subscribe, _ACLCompatibilityMode) - {ok, #{action subscribe}}; parse_rule(all, _ACLCompatibilityMode) - {ok, #{action all}};映射关系总结如下Redis 中存储的规则值兼容模式v4下的含义5.x 原生等价写法1subscribe订阅subscribe2publish发布publish3all全部all继续往下读源码还可以看到除数字与字符串外parse_rule/2还支持 JSON 对象形式如{action:publish,qos:1,retain:true}这部分在 v4 与非 v4 模式下行为一致。若返回的值既不是1|2|3、也不是publish/subscribe/all、更不是合法 JSON 对象则会被判定为非法规则并记录错误日志parse_rule_error该条规则按不匹配处理。四、完整工作链路从配置到鉴权决策为了看清兼容模式在整条授权链路中的位置这里梳理 emqx_authz_redis.erl 的关键调用关系资源生命周期回调create/1、update/2、destroy/1负责创建/更新/销毁 Redis 连接资源其中new_state/2会读取compatibility_mode并通过normalize_acl_compatibility_mode/1归一化取值v4或v4原子都识别为 v4其余一律视为disabled随后对cmd做占位符归一化与模板解析。授权回调authorize/4首先用emqx_auth_template:render_deep_for_raw/2基于当前连接上下文用户名、客户端 ID 等渲染出最终 Redis 命令再通过emqx_authz_utils:cached_simple_sync_query/3走缓存查询查询失败时记录错误日志并按后端失败策略取决于安全配置档返回结果。规则匹配do_authorize/5对查询返回的每一对主题过滤器, 规则值调用parse_rule/2解析构造出带permissionallow的规则映射最终交给emqx_authz_utils:authorize_with_row/6完成与目标 Topic 的匹配命中则返回{matched, Permission}否则继续遍历下一条。另外值得注意的是validate_cmd/1对命令的约束Redis 授权仅接受HGETALL与HMGET两种命令且命令不能为空。这是 Redis 作为授权数据源时查询形态的硬性限制配置cmd时需遵守。五、测试用例如何验证兼容行为兼容模式的正确性在 emqx_authz_redis_SUITE.erl 中有三组针对性用例可直接作为行为规格阅读1.v4_acl_values数字值映射预先写入HMSET acl:username a 1 b 2 d 3cmd为HGETALL acl:${username}compatibility_mode v4。校验结果主题a发布 deny、订阅 allow1→ subscribe主题b发布 allow、订阅 deny2→ publish主题d发布 allow、订阅 allow3→ all2.v4_placeholders_in_cmd_and_topic_filter占位符转换预先写入HMSET mqtt_acl:username pub/%u 2 sub/%c 1cmd为HGETALL mqtt_acl:%ucompatibility_mode v4。校验结果客户端以username连接时允许向pub/username发布命令中的%u被替换返回的主题过滤器pub/%u也被解析为pub/${username}允许订阅sub/clientid%c同理转换为${clientid}。3.v4_acl_values_ignored_without_compat默认模式行为不变同样的1|2|3数据但不设置compatibility_mode。校验结果为所有主题的发布、订阅请求全部 deny——即未启用兼容模式时1|2|3会被当作非法规则忽略原有行为完全不受影响。这正是默认保持禁用现有 Redis 授权行为不变这一设计承诺的直接证据。六、迁移实践与注意事项结合变更文档、源码与测试从 EMQX 4.x 迁移到 5.x 时可参考以下要点确认数据格式检查 Redis 中 ACL 数据的命令模板是否使用了%u/%c占位符规则值是否为1|2|3。只要命中其中一种就需要考虑启用兼容模式。启用方式在authorization.sources的 redis 数据源中设置compatibility_mode v4并保留原cmd如HGETALL mqtt_acl:%u无需改写 Redis 数据本身即可让旧数据重新生效。兼容性影响面v4 模式会同时改变cmd模板与查询结果主题过滤器的占位符解析因此务必在启用后回归验证旧的%u数据是否会与使用${username}的新数据混用两者在 v4 模式下等价可共存。命令约束无论是否启用兼容模式cmd只能是HGETALL或HMGET自定义命令会导致数据源创建或更新失败。安全兜底若旧 ACL 数据中存在非法规则值如拼写错误的pub该条规则会被跳过并打印parse_rule_error日志最终是否放行取决于no_match与安全配置档legacy/hardened的设定建议迁移前先在小范围灰度验证。七、相关文件索引变更文档changes/ee/fix-16730.en.md并收录于 changes/6.1.1.en.md 的 Access Control 章节配置 schema 定义emqx_authz_redis_schema.erl核心实现占位符转换、规则解析、授权回调emqx_authz_redis.erl行为验证测试emqx_authz_redis_SUITE.erl配置项语义描述emqx_authz_redis_schema.hocon【免费下载链接】emqxThe most scalable and reliable MQTT broker for AI, IoT, IIoT and connected vehicles项目地址: https://gitcode.com/gh_mirrors/em/emqx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表