Redis ACL SETUSER细粒度权限控制命令与Key模式
Redis 6.0 引入了 ACL(Access Control List)功能,彻底改变了过去仅靠密码保护所有权限的粗放模式。通过 ACL SETUSER 命令,管理员可以精确控制每个用户能执行哪些命令、操作哪些 Key。这不仅能防止误操作导致的灾难(例如在生产环境执行 FLUSHALL),还能在多租户场景下实现严格的数据隔离。
一、 基础用户创建与启用
在配置细粒度权限前,必须先确立用户身份。Redis 默认有一个 default 用户,我们通常需要创建专用的业务账号。
- 打开 终端并 连接 到 Redis 服务器。
- 输入 以下命令 创建 一个名为
report_user的新用户,同时 设置 密码为strong_pwd:
ACL SETUSER report_user on >strong_pwd
该命令包含三个部分:
report_user:用户名。on:启用该用户(默认为 off,禁用状态无法登录)。>strong_pwd:设定明文密码(Redis 会将其哈希存储)。
- 验证 用户是否创建成功,输入:
ACL LIST
输出结果中应包含 user report_user on #<hash> ... 字样。
二、 命令权限控制(白名单与黑名单)
控制用户能执行什么命令是 ACL 的核心功能。通过 + 和 - 符号,可以灵活组合命令的执行权限。
- 配置 用户仅允许执行只读命令。输入:
ACL SETUSER report_user +@read -@all
解释:
+@read:添加read类别的所有命令(如GET、MGET、SMEMBERS等)。-@all:移除所有类别的命令。- 执行顺序:先执行
+@read,再执行-@all最终会导致无权限。正确的逻辑是先重置或明确允许特定类别。上述命令实际上会先赋予读权限,然后移除所有,结果是无权限。 - 修正操作:需使用
reset或直接明确允许。正确的 重置 并 设置 命令如下:
ACL SETUSER report_user reset +@read
reset 关键字会清除该用户之前所有的规则(包括密码和开关),因此通常在创建初期配合使用,或者重新补全密码。为保留密码,我们 使用 负号排除非读命令更为稳妥:
ACL SETUSER report_user -@write -@admin -@dangerous
- 允许 特定的单个写命令。例如,允许
report_user使用SET命令但禁止其他写命令:
ACL SETUSER report_user +SET
- 禁止 执行高危命令。即使赋予了
+@all,也可以 单独屏蔽FLUSHDB或KEYS:
ACL SETUSER report_user -FLUSHDB -KEYS
三、 Key 模式匹配(细粒度数据隔离)
这是 ACL 最强大的功能。使用波浪号 ~ 后接 Glob 风格的模式,可以限制用户只能访问特定前缀或格式的 Key。这相当于在 Key 层面做了“视图”控制。
- 切换 到管理员账号(default 或有 ACL 权限的账号)。
- 配置
report_user只能操作以report:2023:开头的 Key:
ACL SETUSER report_user ~report:2023:*
此时,即使用户拥有 +@all 权限,尝试访问 user:1001 也会被拒绝。
-
测试 权限隔离效果。
- 切换 到
report_user登录:
AUTH report_user strong_pwd- 尝试 设置允许的 Key:
SET report:2023:daily_traffic "500GB"- 尝试 设置被禁止的 Key:
SET system:config "debug_mode"第二条命令将返回
NOPERM错误,提示用户没有权限访问该 Key。 - 切换 到
为了更直观地理解 Redis 处理权限的流程,请参考以下决策逻辑:
四、 常用 Key 模式语法表
掌握 Glob 风格的通配符是配置 Key 权限的关键。下表列出了常用的模式匹配规则:
| 模式语法 | 描述 | 匹配示例 | 不匹配示例 |
|---|---|---|---|
~prefix:* |
匹配特定前缀的所有 Key | user:1, user:name |
my_user:1 |
~*:<suffix> |
匹配特定后缀的所有 Key | data:cache, temp:cache |
cache:data |
~object:? |
问号匹配任意单个字符 | key:a, key:b |
key:ab, key: |
~users:[0-9]* |
支持方括号内的字符范围 | users:1, users:2a |
users:a |
~my?data_* |
混合使用通配符 | my1data_temp, my2data_ |
mydata_temp |
五、 综合实战:构建订单服务专用账号
假设我们有一个微服务“订单服务”,它需要:
- 读写自己的订单数据。
- 只能读取公共配置数据。
- 禁止删除任何数据。
- 禁止访问用户模块的敏感数据。
我们可以通过一条复合命令完成配置,或者分步执行。以下分步操作流程清晰明了:
- 创建 用户
order_service并 设置 密码s3cr3t!:
ACL SETUSER order_service on >s3cr3t!
- 赋予 基础命令权限。赋予普通读写权限,移除管理/危险命令:
ACL SETUSER order_service +@read +@write -@admin -@dangerous -FLUSHALL -FLUSHDB
- 配置 Key 空间访问权限。
- 允许读写
order:*前缀。 - 允许只读
config:public:*前缀。 - 注意:Key 模式之间是“或(OR)”的关系,即只要匹配任意一个模式即可。
- 允许读写
ACL SETUSER order_service ~order:* ~config:public:*
- 进一步收紧 写权限。虽然
order:*允许了读写,但我们希望config:public:*是只读的。由于 ACL 目前不支持针对特定模式绑定特定子命令(例如针对~config:*仅允许GET而禁止SET),我们需要在命令层面进行调整。- 撤销
+@write(因为SET、DEL等都在写分类中)。 - 手动添加 订单服务所需的特定写命令(如
SET、INCR、LPUSH、SADD)。
- 撤销
假设订单服务主要用到字符串和列表操作:
ACL SETUSER order_service -@write +SET +INCR +LPUSH +RPUSH +SADD +HSET +HMSET +XADD
此时,用户拥有所有读权限(包括读 config),但只有针对特定数据结构的写权限。为了防止误删,我们依然保持 DEL 命令不在列表中(或者显式禁止):
ACL SETUSER order_service -DEL
六、 持久化与配置文件
通过命令行 ACL SETUSER 修改的权限默认是保存在内存中的。如果 Redis 重启,配置将丢失(除非使用了 ACL SAVE 命令将其保存到配置文件,但在生产环境中通常直接编辑配置文件)。
- 生成 当前 ACL 配置的
redis.conf格式文本。输入:
ACL SAVE
这会将内存中的用户定义 追加 到 Redis 配置文件(通常是 redis.conf)的末尾。
- 查看 配置文件内容(在服务器上使用
tail或cat命令):
tail -n 20 /etc/redis/redis.conf
你将看到类似如下的文本:
user report_user on #<hash> ~report:2023:* +@read
user order_service on #<hash> ~order:* ~config:public:* -@write +SET +INCR ...
- 确保 Redis 启动时加载 ACL。在
redis.conf的主配置区域,确保aclfile指令指向了正确的文件,或者直接包含在主配置文件中。如果使用外部 ACL 文件,推荐 使用aclfile指令:
aclfile /etc/redis/users.acl
此时,执行 ACL LOAD 可以重载该文件而不重启 Redis(仅在运行时生效),但重启后 Redis 会自动读取该文件。
- 验证 配置文件语法是否正确。输入:
ACL LOAD
如果文件有误(例如密码哈希格式错误),Redis 会返回错误信息且不会应用错误配置。

暂无评论,快来抢沙发吧!