当前位置:首页 > 文章列表 > 数据库 > Redis > Redis ACL SETUSER 怎样限制可访问命令

Redis ACL SETUSER 怎样限制可访问命令

来源:17golang原创 2026-11-06 14:31:31 0浏览 收藏

Redis 的 ACL SETUSER 可以限制用户能执行哪些命令,但“允许命令”不等于“允许所有键”。要把一个应用账号收窄到可用范围,至少要同时配置命令规则和键模式;否则可能出现命令已经放行,却因为键范围不足仍然返回 NOPERM。

官方地址:https://redis.io/docs/latest/commands/acl-setuser/

最稳妥的做法是先用 reset 清空旧规则,再显式写入 on、密码、最小命令集合和键模式。单个命令长期更容易审查;命令分类适合快速建立边界;Redis 7.0 及以上还可以用选择器把不同命令绑定到不同键前缀。

ACL SETUSER 实际限制了哪两层权限

ACL 判断可以拆成两层:第一层判断用户是否有权调用某条命令,第二层判断这条命令访问的键是否匹配允许的模式。+get 只解决第一层,~cache:read:* 主要解决第二层,两者缺一不可。

规则作用常见误区
+get / -set允许或拒绝单个命令以为允许 GET 后就能读任意键
+@read / -@dangerous按 ACL 命令分类批量调整忽略分类会随版本和模块边界变化
~cache:read:*允许匹配模式的键访问把键模式当成命令白名单
nocommands清空可执行命令集合忘记随后补回需要的命令
Redis ACL SETUSER 命令权限、命令分类与键模式的静态结构图
图1:Redis ACL 的命令规则、命令分类和键模式是相互配合的权限边界;这是静态说明图,不是运行截图。

先用 reset 重建一个只读账号

如果用户以前已经配置过规则,直接追加 +get 并不会自动删除旧权限。下面的写法先恢复默认能力,再重新打开账号、设置密码、允许读取命令,并把键范围限定在 cache:read: 前缀。

# 先清理旧规则,再创建只读用户;密码参数用引号避免被 Shell 特殊解析
redis-cli ACL SETUSER app-reader reset on '>ChangeThisPassword' nocommands +get +mget '~cache:read:*'

# 查看用户的命令、键模式和启用状态;这是配置检查,不会修改 ACL
redis-cli ACL GETUSER app-reader

# 查看当前连接实际认证成哪个用户,避免把规则改在错误账号上
redis-cli ACL WHOAMI

reset 会把用户恢复成关闭、无密码、无命令、无键权限的状态,所以后面必须补上 on 和需要的规则。nocommands 的作用是显式清空命令集合,和 reset 一起使用时,配置意图更清楚,也能避免未来维护者误以为命令是从旧规则继承来的。

这条规则只允许 GET 和 MGET,而且键名要匹配 cache:read:*。因此,用户即使认证成功,也不应该能够调用 SET 或读取 cache:write:1。

单命令和命令分类应该怎么选

需要长期稳定审查的生产账号,优先写单命令。例如只读缓存账号可以明确列出 +get +mget +exists;写入账号再按业务补充 +set、+del 等实际需要的命令。这样做的优点是规则与代码调用关系直接对应,缺点是新增业务命令时需要同步修改 ACL。

# 单命令白名单:只开放读取缓存所需的三个命令
redis-cli ACL SETUSER app-reader reset on '>ChangeThisPassword' nocommands +get +mget +exists '~cache:read:*'

# 分类适合快速建立只读边界;再按部署策略排除不希望开放的命令
redis-cli ACL SETUSER report-reader reset on '>ChangeThisPassword' nocommands +@read '~report:*'

# 查看某个分类实际包含哪些命令;分类内容以当前 Redis 实例为准
redis-cli ACL CAT read

+@read 是按分类授权,不应被理解成“所有模块的所有读取命令”。Redis 官方文档说明,除 +@all 外,普通分类不包含模块命令;因此引入模块或新能力后,仍要按实例的 ACL CAT 结果和应用调用清单复查。若安全边界要求可审计,宁可多写几个单命令,也不要为了省配置把权限扩大到不需要的类别。

Redis 7.0 以上怎样限制子命令

从 Redis 7.0 开始,ACL 可以用竖线区分命令和子命令。例如允许 CONFIG GET,同时拒绝 CONFIG SET,可以把根规则写成:

# 只放行 CONFIG GET 子命令,不把整个 CONFIG 管理面交给应用账号
redis-cli ACL SETUSER config-reader reset on '>ChangeThisPassword' nocommands +config|get '~app:config:*'

# 如果要封锁某个已放开的子命令,Redis 7.0 起可以使用 -command|subcommand
redis-cli ACL SETUSER ops-user -config|set

这里的竖线是 ACL 规则语法的一部分。在 Shell 中直接执行带竖线的参数时,建议把整个规则用单引号包住,否则 Shell 可能把它解释成管道。不要把“允许第一个参数”的旧式写法和子命令选择器混为一谈;官方文档把 first-arg 机制标记为已弃用,而 Redis 7.0 的子命令规则更适合表达明确边界。

同一用户需要两组键范围时用选择器

如果一个账号既要读取公共缓存,又只能写入自己的业务前缀,可以使用 Redis 7.0 引入的 selectors。根权限和每个选择器分别保存一组规则;命令请求只要匹配根权限或任一选择器即可通过,因此每个选择器中的命令和键模式要成对设计。

# 根权限只读公共缓存;选择器只允许写入业务写入前缀
redis-cli ACL SETUSER app-worker reset on '>ChangeThisPassword' nocommands +get +mget '%R~cache:read:*' \
  '(+set +expire %W~cache:write:*)'

# 读取用户的 selectors 与根权限,确认规则是否按预期保存
redis-cli ACL GETUSER app-worker

如果部署版本还没有 Redis 7.0 的 selector 和读写键权限语法,就退回到单一键模式,或者拆分成两个账号。选择器增加了表达力,也增加了审查成本;只有在同一连接确实需要多组权限时才值得引入。

Redis ACL 用户权限、选择器与 NOPERM 排查线索的静态关系图
图2:app-reader 的命令、键范围、Redis 7.0 选择器和 NOPERM 线索之间的静态关系;这是结果说明图,不是执行证据。

遇到 NOPERM 时按三个方向排查

NOPERM 说明用户已经认证,但当前 ACL 不允许执行命令或访问键。不要只盯着 +get,可以按下面顺序缩小范围:

  1. 确认身份:执行 ACL WHOAMI,确认连接不是仍然使用 default 用户。
  2. 确认命令:用 ACL GETUSER username 查看命令规则,必要时用 ACL CAT category 查看分类实际包含的命令。
  3. 确认键和子命令:检查键名是否匹配 ~、%R~ 或 %W~,以及调用的是否是被单独封锁的子命令。
# 读取最近的 ACL 拒绝记录;重点看 user、reason 和 object 字段
redis-cli ACL LOG 10

# 用最小测试分别验证命令拒绝和键拒绝;不要在生产键上随意写入
redis-cli --user app-reader --pass 'ChangeThisPassword' GET cache:read:demo
redis-cli --user app-reader --pass 'ChangeThisPassword' SET cache:read:demo value

如果第一条 GET 因键模式不匹配失败,日志通常会把原因指向键;如果第二条 SET 失败,则更可能是命令权限不足。测试命令只应使用专门的测试键,密码也应由安全的凭据注入方式提供,示例中的字符串不能直接作为生产密码。

一份可落地的权限决策表

需求推荐规则注意点
只读一个键前缀nocommands +get +mget ~cache:read:*命令和键模式同时写
只开放一组稳定命令逐个使用 +command新增调用时同步审查
快速建立读取边界+@read用 ACL CAT 查看实际范围
限制 Redis 7.0 子命令+config|get、-config|setShell 中给规则加引号
同账号多组键范围使用 selector增加审查复杂度,旧版本不支持

最后再强调一次:ACL SETUSER 修改已有用户时默认是追加或调整现有规则,不会自动替你“收敛”到最小权限。正式改造时,把 reset、账号状态、认证方式、命令清单、键前缀和回滚方式一起写进变更记录,避免只改了一个 +command 就误以为边界已经完成。

相关问题

  • 为什么有 +get 仍然返回 NOPERM? 因为命令允许和键模式允许是两层检查,键名还必须匹配规则。
  • +@read 能代替所有只读命令吗? 不能直接假设,应该用当前实例的 ACL CAT read 查看,并注意模块命令边界。
  • 修改 ACL SETUSER 后旧连接会立刻失效吗? 用户关闭后,已经认证的连接仍可能继续工作;需要按官方 ACL 管理方式处理存量连接。
  • 什么时候不该使用 selector? 当账号只需要一组稳定的命令和键范围时,单命令加单键模式更容易审查和回滚。
版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Redis LCS 加上 LEN 为什么仍不适合大字符串Redis LCS 加上 LEN 为什么仍不适合大字符串
上一篇
Redis LCS 加上 LEN 为什么仍不适合大字符串
Redis CLIENT LIST TYPE 怎样筛选连接类型
下一篇
Redis CLIENT LIST TYPE 怎样筛选连接类型
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之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模型性能。
    912次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    919次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    998次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    992次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    813次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码