Redis ACL 怎样限制客户端只能访问指定命令
来源:17golang原创
时间:2026-11-03 16:01:57 255浏览 收藏
Redis ACL 的关键不是只给客户端设置一个密码,而是同时限制“能执行哪些命令”和“这些命令能作用于哪些键”。如果一个缓存客户端只需要读取 cache: 前缀下的数据,可以创建一个新用户,给它 +get +mget,再给它 ~cache:*;这样它既不能执行 SET,也不能读取其他业务前缀。
官方地址:https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl/
最稳妥的做法是从新用户的零权限状态开始,先写清楚命令集合,再写键模式,最后用 ACL GETUSER 和一组允许/拒绝请求复查。命令权限正确但键模式过宽,仍然不是最小权限。
先把命令权限和键权限分开
Redis ACL 的规则按从左到右应用,但不同规则解决的是不同问题:
| 规则 | 限制对象 | 示例 |
|---|---|---|
+get | 允许一个命令 | 只允许读取字符串值 |
+@read | 允许一个命令类别 | 允许读类命令集合 |
~cache:* | 允许访问的键模式 | 只匹配 cache: 前缀 |
resetchannels | 清空 Pub/Sub 通道模式 | 不让账号默认访问频道 |
因此,+get 不等于“可以读取所有键”,~cache:* 也不等于“可以执行读写命令”。两者需要一起出现,才能表达“只能用 GET 读取某个范围”。

从零创建一个只读缓存用户
新建用户默认是关闭状态、没有密码、没有可执行命令,也没有键模式。可以利用这个安全起点明确写入完整规则。下面的示例给业务账号开放 GET 与 MGET,只允许访问 cache: 前缀。
# 使用管理员身份创建最小权限用户;密码占位符要替换为密钥管理系统提供的值 redis-cli --user admin --pass 'admin-password' ACL SETUSER cache_reader reset on >ReplaceWithLongSecret resetchannels ~cache:* +get +mget # 查看用户最终的 flags、commands、keys 和 channels redis-cli --user admin --pass 'admin-password' ACL GETUSER cache_reader
reset 会清掉旧密码、键模式、通道和命令授权,并把用户恢复到关闭且无权限的初始状态;随后再用 on、密码、键模式和命令规则逐项打开能力。这里显式加入 resetchannels,是为了避免把 Pub/Sub 访问范围和键访问混在一起。
生产环境不要把真实密码写进脚本或文章。示例中的 ReplaceWithLongSecret 只是占位符;创建用户后应通过安全的凭据分发方式让客户端使用双参数认证:
# 以明确的用户名认证,而不是继续依赖权限过大的 default 用户 redis-cli --user cache_reader --pass 'ReplaceWithLongSecret' GET cache:1234
精确命令和命令类别怎么选
如果业务调用面很小,精确列出命令最容易审查。例如只读一个字符串缓存时用 +get,批量读取再加上 +mget。如果业务会使用一组稳定的读命令,可以用 +@read,但它的范围比两个命令更大,升级或模块变化时需要重新检查。
# 先查看当前 Redis 实例中的命令类别,避免凭记忆猜类别内容 redis-cli --user admin --pass 'admin-password' ACL CAT read # 精确授权:只允许 GET 和 MGET,适合调用面固定的缓存读取器 redis-cli --user admin --pass 'admin-password' ACL SETUSER cache_reader +get +mget # 类别授权:适合读命令集合明确、可以接受更宽命令面的服务 redis-cli --user admin --pass 'admin-password' ACL SETUSER report_reader reset on >ReplaceWithLongSecret ~report:* +@read
不建议把 +@all -@dangerous 当作默认的“只读”方案。官方文档明确指出,+@all 还会包含模块加载的命令,而命令类别本身通常不包含模块命令;用“先全部允许再排除少量危险命令”的写法,很容易遗漏未来出现的能力。要限制一个业务账号,优先用精确命令或小范围类别。

键模式决定“能读哪里”
命令授权通过后,Redis 还会检查命令参数里涉及的键是否匹配用户的键模式。~cache:* 允许匹配 cache: 开头的键,不能把它误写成 ~*,后者会覆盖整个键空间。
# 为同一个用户增加第二个业务前缀;每个模式都应有明确的业务用途 redis-cli --user admin --pass 'admin-password' ACL SETUSER cache_reader ~session:* # 如果决定完全替换旧的键范围,先清理再写入新模式 redis-cli --user admin --pass 'admin-password' ACL SETUSER cache_reader resetkeys ~cache:*
Redis 7 及以后还提供只读和只写键模式,例如 %R~cache:* 与 %W~cache:*。如果应用只需要读,可以把命令集合和键权限都收窄;不过最终仍要以目标 Redis 版本的命令参考和实际客户端调用面为准。
用 ACL GETUSER 和 NOPERM 复查结果
ACL GETUSER 返回 flags、密码摘要、commands、keys、channels 和 selectors 等字段。检查时至少确认四点:用户是 on、命令列表没有意外的 +@all、键模式没有无意的 ~*、通道权限符合业务需要。
# 读取机器可解析的用户描述;重点关注 commands、keys 和 channels redis-cli --user admin --pass 'admin-password' ACL GETUSER cache_reader # 允许的命令和键应成功,未授权的命令或键应返回 NOPERM redis-cli --user cache_reader --pass 'ReplaceWithLongSecret' GET cache:1234 redis-cli --user cache_reader --pass 'ReplaceWithLongSecret' SET cache:1234 changed redis-cli --user cache_reader --pass 'ReplaceWithLongSecret' GET other:1234
预期是第一条读取请求可以执行,后两条分别因没有 set 命令权限、键不匹配 cache:* 而返回 NOPERM。这组复查不会证明所有业务路径都覆盖到了,但可以快速发现最常见的“命令放宽”或“键范围放宽”。
增量修改时最容易踩的坑
多次调用 ACL SETUSER 不会自动重置已有用户,而是把新规则增量应用到当前用户。比如先加 +set,再加 +get,最后会同时拥有两个命令。需要重做权限时显式使用 reset,需要扩展权限时则把变更记录成可审查的最小差异。
另外,命令类别可能重叠,一个命令可以属于多个类别;不要只看类别名称推断最终集合,应该用 ACL CAT 列出当前实例的实际内容。对管理账号、迁移脚本和运维工具,更应该单独建立用户,避免把 CONFIG、FLUSHALL、DEBUG 等管理能力交给普通业务连接。
结论:按业务调用面给权限
| 业务场景 | 命令策略 | 键策略 |
|---|---|---|
| 只读缓存 | +get +mget | ~cache:* |
| 报表读取 | 经审查的 +@read | ~report:* |
| 读写单一业务前缀 | 精确列出读写命令 | ~order:* 或更细的读写模式 |
| 运维管理 | 独立账号,单独审批 | 不要复用业务账号的键模式 |
相关问题
只写键模式能阻止客户端执行 SET 吗?
不能。键模式只限定键范围,仍然需要用命令规则控制 SET 或其他写命令。
+@read 是不是等于只读?
它表示允许当前实例定义的读类命令,不等于只允许某一两个命令;还要结合键模式,并检查命令类别实际内容。
为什么 ACL SETUSER 之后旧连接权限没有立刻符合预期?
ACL 规则修改的是用户权限,已有连接的认证状态和客户端调用仍要单独观察。先用新连接按用户名认证复查,再检查连接池是否复用了旧连接。
-
111 收藏
-
186 收藏
-
372 收藏
-
245 收藏
-
440 收藏
-
151 收藏
-
123 收藏
-
353 收藏
-
249 收藏
-
163 收藏
-
368 收藏
-
117 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习