登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  数据库 >  Redis

Redis ACL Selector 怎么给同一用户配置多组规则

来源:17golang原创

时间:2026-10-05 02:01:36 295浏览 收藏

同一个 Redis 用户如果同时服务两个业务空间,不必复制成两个账号。Redis 7.0 及以上可以在 ACL SETUSER 中用括号添加多个 Selector:根权限和每个 Selector 是可独立匹配的权限集合,只要其中一组同时匹配命令与 key,操作就会被允许。

官方地址:https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl/

要点速览
  • Selector 是多组可选规则,不是把所有括号条件强行叠成一组。
  • 同一 Selector 内,命令权限和 key 模式仍要同时满足。
  • Selector 添加后不能单独编辑,批量变更应先清除再完整重建。
实操时先把根权限收紧到 -@all,再为每条业务路径写一个括号组。这样权限表能直接回答“允许哪些命令访问哪些 key”,也不容易因为旧规则残留而放大权限。

先建立两组权限的基线

假设一个账号 reporter 要读取 tenant:a: 下的数据,同时向 tenant:b: 写入结果。基线很小:1 个用户、2 个 key 前缀、2 组操作。这里不能把两组规则写成一个大集合,否则“能读 A、能写 B”的边界会被误解成“能读写 A 和 B”。

Selector 从 Redis 7.0 开始提供。括号外是用户的根权限,括号内的每个规则列表都是一个独立 Selector。下面用 shell 注释标出每条命令的目的:

# 创建用户并关闭默认的全量命令权限;密码仅作示例,生产环境应使用密钥管理
redis-cli ACL SETUSER reporter on >change-me -@all

# 第一组:只允许读取 tenant:a: 前缀
redis-cli ACL SETUSER reporter "(+@read ~tenant:a:*)"

# 第二组:只允许写入 tenant:b: 前缀
redis-cli ACL SETUSER reporter "(+@write ~tenant:b:*)"

命令行中括号需要作为一个参数传给 Redis;在不同 shell 下建议保留双引号。密码不要照搬示例,且不要把真实密码提交到脚本仓库。

Redis ACL Selector 根权限与两个 key 前缀权限组的静态结构说明图
图1:Redis ACL Selector 权限分组说明图,展示根权限与两组命令、key 模式的独立边界。

理解 Selector 的匹配方式

判断一条请求时,Redis 先看根权限,再按添加顺序看 Selector。根权限或任意一个 Selector 匹配成功即可放行;但进入某个 Selector 后,命令类别和 key 模式不能只满足一半。

例如,GET tenant:a:42 会命中第一组;SET tenant:b:42 value 会命中第二组;SET tenant:a:42 value 的 key 虽在第一组范围内,但第一组没有写权限,因此应被拒绝。反过来,GET tenant:b:42 也不会因为第二组允许写入而获得读取权限。

# 只做权限判断,不执行实际读写;输出应分别接近有权限和无权限
redis-cli ACL DRYRUN reporter GET tenant:a:42
redis-cli ACL DRYRUN reporter SET tenant:a:42 value
redis-cli ACL DRYRUN reporter SET tenant:b:42 value

# 检查当前用户的规则文本,确认括号组没有被写错
redis-cli ACL LIST | grep 'user reporter'

生产检查可以把每个业务前缀选一个代表 key,再覆盖一条跨前缀请求。不要只验证“命令对不对”,还要验证 key 模式是否命中;ACL 的安全边界通常就在这两个条件的交集里。

用 ACL GETUSER 查看和重建规则

ACL LIST 适合快速查看整行规则,ACL GETUSER 更适合程序或人工分字段读取。重点看 commands、keys 和 selectors,不要只看用户是否为 on。

# 用结构化字段查看 reporter,避免只凭 ACL LIST 的长字符串判断
redis-cli ACL GETUSER reporter

# 变更 Selector 前先保存一份当前规则,便于回滚和审计
redis-cli ACL LIST | grep 'user reporter' > reporter-acl.backup

根权限可以通过后续 ACL SETUSER 增量调整,但已经添加的 Selector 不能单独修改。若要把 tenant:b: 改成 tenant:c:,建议使用完整清单重建:

# 清空该用户所有 Selector,根权限仍然保留
redis-cli ACL SETUSER reporter clearselectors

# 按审计后的完整清单重新添加两组权限
redis-cli ACL SETUSER reporter "(+@read ~tenant:a:*)" "(+@write ~tenant:c:*)"

# 重建后再次读取 selectors,并执行一正一反两组 DRYRUN
redis-cli ACL GETUSER reporter
redis-cli ACL DRYRUN reporter SET tenant:b:42 value

clearselectors 不会清除根权限;如果需要从零重置用户,要明确使用 reset,再重新设置 on、密码、key 和命令规则。两者影响范围不同,不能混用。

Redis ACL GETUSER 检查 Selector 字段与 clearselectors 重建边界的静态说明图
图2:规则检查与重建说明图,区分 ACL GETUSER 的字段视图、Selector 清理和根权限保留。

上线前的权限检查清单

检查项应看到的结果常见误区
版本Redis 7.0 及以上旧版本不支持括号 Selector
根权限按需保留,通常先用 -@all 收紧根权限已有 +@all,导致 Selector 形同虚设
每组规则命令和 key 模式都明确只限制命令,忘记限制 key
变更方式保存旧规则,清除后完整重建误以为重复 SETUSER 会编辑旧 Selector

最后用 ACL DRYRUN 覆盖“允许读 A、拒绝写 A、允许写 B、拒绝读 B”四个方向。若使用的是 Redis Cloud 或 Redis Software,还要先核对产品版本和管理面支持范围,不能把开源 Redis 的命令行行为直接套过去。

常见问题

多个 Selector 是 AND 关系吗?

不是。根权限或任意一个 Selector 匹配即可允许;同一 Selector 内的命令和 key 条件仍需同时满足。

可以只修改某一个已经存在的 Selector 吗?

不能把它当成可编辑对象。稳妥做法是保存规则,执行 clearselectors,再一次性添加完整的新 Selector 集合。

为什么限制了 Selector,用户仍能访问所有 key?

先检查根权限是否包含 ~*、allkeys 或过宽的命令组。Selector 不是额外的拒绝层,根权限命中时请求仍会被允许。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>