当前位置:首页 > 文章列表 > 数据库 > Redis > Redis ACL 的 key pattern 为什么放行了意外键

Redis ACL 的 key pattern 为什么放行了意外键

来源:17golang原创 2026-09-15 11:34:47 0浏览 收藏

我排查 Redis ACL 时,最容易误判的一点是:看到用户配置了 ~tenant-a:*,就以为它只能访问这一组键。实际上,Redis 会把同一个用户已有的 key pattern、命令权限和 selector 一起计算;旧规则没有清掉、通配符范围过宽,或者命令本身不带具体 key,都可能让“意外键”看起来被放行。

先执行 ACL GETUSER 用户名 看生效规则,再用 ACL DRYRUN 用户名 命令 参数 做无副作用验证。最稳妥的修复方式是以 reset 重建权限,明确区分根规则和 selector,而不是继续追加一个更窄的 pattern。
要点速览
  • ~pattern 是 glob 风格匹配,~*allkeys 会覆盖所有键。
  • ACL SETUSER 默认是在已有规则上追加;规则和 selector 只要有一组完整匹配,就可能获得许可。
  • 不带 key 参数的数据库级命令不受 key pattern 限制,必须单独收紧命令权限。

先把真正生效的规则展开

不要只看部署文件里最近改的那一行。Redis 官方文档说明,ACL SETUSER 会从左到右处理规则;用户已存在时,新调用通常是在原规则上应用变更。先查根规则、键规则和 selector:

# 读取用户当前的完整 ACL,包括根权限和 Redis 7.0+ selector
ACL GETUSER app_reader

# 以 ACL 文件格式查看所有用户的有效规则,便于发现 ~* 或 allkeys
ACL LIST

# 在不真正执行命令的前提下,模拟 app_reader 访问另一租户的键
ACL DRYRUN app_reader GET tenant-b:profile:42

如果回显的 keys 同时有 ~tenant-a:*~*,答案已经很明确:后者覆盖了前者。若 selectors 里还有一组包含 ~* 或更宽 pattern 的规则,也要一并处理。ACL GETUSER 展示的是用户的有效规则,适合用来对照配置文件和变更记录。

这是Redis ACL key pattern使用通配符匹配时的常见坑:默认规则下`*`、`?`这类通配符的匹配范围比多数开发者预期更广,没有转义特殊字符、或者pattern前缀后缀遗漏边界限制,就会把原本不在权限规划内的键也放行了。排查时优先核对pattern的字符转义规则、键名的实际字符组成,就能快速定位问题根源。
Redis ACL 根权限、selector 与 key pattern 范围的结构示意图
图1:Redis ACL 根规则与 selector 的 key pattern 范围示意图,帮助定位覆盖范围过宽的配置。

为什么窄 pattern 仍会放行意外键

我通常按下面四个边界逐一排除,避免把“键名匹配”误当成“所有访问都取交集”。

检查点常见配置实际含义
通配符~tenant-*glob 匹配,范围可能包含多个租户,而非前缀的精确等值。
历史规则先有 ~*,后加窄规则追加窄规则不会自动删除旧的宽规则。
selector(+GET ~*)根权限或任一 selector 完整匹配时即可通过,不能把它理解成两者相交。
无 key 命令FLUSHDBFLUSHALL没有具体 key 参数,key pattern 本身无法限制它们。

Redis 7.0 起还可以写 %R~pattern%W~pattern,分别限制读、写方向。跨键命令要特别小心:例如把 tenant-b: 的数据复制到 tenant-a:,同一组权限需要分别覆盖源键的读取和目标键的写入;只给其中一个 pattern,不能得到你想要的跨键能力。

用重建而不是叠加修正权限

如果用户是专用业务账号,我更愿意明确重置后再写规则。下面是一个只允许读取和写入 tenant-a: 的示例;密码仅作占位,生产环境不要把真实密码写进脚本或日志。

# reset 先清掉旧的命令、key 和密码规则,避免历史 ~* 残留
ACL SETUSER app_writer reset on >replace-with-secret +GET +SET +DEL ~tenant-a:*

# Redis 7.0+ 可把读写边界拆开;按需选择,不要与 ~* 混用
ACL SETUSER app_reader reset on >replace-with-secret +@read %R~tenant-a:*

# 把高风险的数据库级命令显式移除,它们不靠 key pattern 约束
ACL SETUSER app_writer -FLUSHDB -FLUSHALL -SWAPDB

“最小权限”不等于只写一个 pattern。还要确认命令集合、事务或脚本使用的命令,以及应用是否需要跨键操作。若账号要执行 HGETHSET,不要只开放一个与数据结构不匹配的命令类别;按真实调用清单逐项增加。

用 DRYRUN 验证允许、拒绝和高风险路径

ACL DRYRUN 从 Redis 7.0 提供无副作用的模拟执行,特别适合把“我以为会拒绝”变成可复查的结果。建议至少覆盖三类键和一类无 key 命令:

# 允许的键:预期返回 OK(以下是示例回显,不代表本文在你的实例执行)
ACL DRYRUN app_writer SET tenant-a:profile:42 active
# OK

# 另一租户:预期返回没有 key 权限
ACL DRYRUN app_writer GET tenant-b:profile:42
# User app_writer has no permissions to access the key

# 无 key 参数的高风险命令:检查它是否仍在命令集合中
ACL DRYRUN app_writer FLUSHALL
# User app_writer has no permissions to run the 'flushall' command

如果意外键仍然返回 OK,回到 ACL GETUSER 搜索所有根 pattern 和 selector,再检查应用实际认证的用户名:连接复用、默认用户和 AUTH/HELLO 切换都可能让你查的是 app_reader,用的却是另一个用户。

Redis ACL DRYRUN 对允许键意外键和无 key 命令的验证矩阵示意图
图2:使用 ACL DRYRUN 对允许键、意外键和数据库级命令做结果验证的示意图。

上线前留一张小清单

  • ACL GETUSER 确认没有遗留 ~*allkeys 或意外 selector。
  • 用真实命令逐个跑 ACL DRYRUN,至少包含读、写、删除、跨键和无 key 参数命令。
  • ACL SETUSER 变更写成可重复的声明式脚本,修改前优先 reset,并保留回滚版本。
  • 确认业务连接认证的用户名与检查时一致,再让灰度流量验证拒绝路径。

常见问题

只写了 ~tenant-a:*,为什么还能访问别的键?

最常见是旧规则仍包含 ~*,或 selector 中存在更宽的 pattern。先看 ACL GETUSERkeysselectors

~pattern 能限制 FLUSHALL 吗?

不能。FLUSHALL 没有具体 key 参数,需从命令权限中移除;同理检查 FLUSHDBSWAPDB 等数据库级命令。

Redis 6 能使用 ACL DRYRUN 吗?

不能把它作为 Redis 6 的通用检查手段;官方命令文档标注 ACL DRYRUN 从 Redis 7.0 起提供。旧版本应在隔离环境用测试账号和真实命令验证。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go TLS InsecureSkipVerify 为什么只影响客户端校验Go TLS InsecureSkipVerify 为什么只影响客户端校验
上一篇
Go TLS InsecureSkipVerify 为什么只影响客户端校验
Go compress/gzip Header.ModTime 如何控制归档可复现性
下一篇
Go compress/gzip Header.ModTime 如何控制归档可复现性
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    31次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    135次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    70次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    27次使用
  • CMMLU中文大模型评估基准:功能、使用教程与应用场景解析
    CMMLU
    深入了解CMMLU中文评估基准,涵盖67个学科主题,提供数据集下载、Zero-shot/Five-shot评估方法及排行榜,助力优化中文语言模型性能。
    16次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码