Redis 7 + ACL 简介
摘要
- Redis 7 + ACL 简介
- 本文基于
redis-7.4.7 - Redis官网:https://redis.io/
Redis ACL 简介
-
从 Redis 6.0 开始,引入了 ACL 功能,用来精细化控制不同用户能做什么,代替过去只有一个全局密码(requirepass)的粗粒度模式。
-
ACL 可以控制的维度包括:
- 谁能登录(用户、密码)
- 可以执行哪些命令
- 可以访问哪些 key(按前缀 / 正则)
- 可否通过网络访问
- 是否启用 / 禁用某个用户
-
一句话:Redis ACL 实现了多用户 + 权限最小化 + 资源隔离
Redis ACL 的使用
-
在
redis.conf中添加如下内容:
1 | # 指定 ACL 文件 |
-
也可以不配置
aclfile,而是将用户信息直接编写在redis.conf中,但不建议这样做。
ACL 的配置方式
直接编辑 aclfile
-
创建一个
users.acl文件,并写入如下内容:
1 | # 配置一个管理员 |
-
这里要特别注意,aclfile 不支持注释行,所有行都必须以 user 开头,否则会报错。
-
格式说明
1 | user: 固定前缀 |
-
为了兼容以前的版本,Redis 提供了一个默认的用户:
default,不指定用户名的时候,默认使用的就是default用户,其对应的acl权限为
1 | # 实际上就是一个超级管理员权限 |
-
开启
ACL后,推荐关闭default用户。
1 | # 关闭默认用户,禁止匿名访问 |
-
登录redis
1 | # 连接时直接登录, --pass == -a |
-
Redis ACL 规则中文说明
| 规则 / 语法 | 中文说明 |
|---|---|
on |
启用用户:可以使用该用户进行认证登录 |
off |
禁用用户:无法再使用该用户认证,但已认证的连接仍然有效 |
skip-sanitize-payload |
跳过对 RESTORE 命令的 dump 数据载荷过滤(跳过安全检查) |
sanitize-payload |
对 RESTORE 命令的 dump 数据载荷进行过滤(默认) |
+<command> |
允许执行指定命令;可以指定子命令,例如:+config | get |
-<command> |
禁止执行指定命令;可以指定子命令,例如:-config | set |
+@<category> |
允许一个命令分类的所有命令,如:@admin, @set, @sortedset 等。完整分类在 server.c 的命令表中 |
@all |
特殊分类,表示所有当前已有命令 + 未来模块加载的命令 |
+<command>|first-arg |
只允许使用某命令的第一个参数(已废弃,将可能移除);只支持新增,不支持禁止(如 -SELECT|1 不允许) |
allcommands |
+@all 的别名,允许所有命令(包括将来可能加载的模块命令) |
nocommands |
-@all 的别名,禁止所有命令 |
~<pattern> |
添加允许访问的 key 模式(glob 风格),如:~user:*;可以有多个 |
%R~<pattern> |
添加允许读取的 key 模式 |
%W~<pattern> |
添加允许写入的 key 模式 |
allkeys |
~* 的别名,允许所有 key |
resetkeys |
清空允许访问的 key 模式 |
&<pattern> |
添加可访问的 Pub/Sub channel 模式(glob 风格),可多个 |
allchannels |
&* 的别名,允许所有 channel |
resetchannels |
清空 Pub/Sub channel 模式列表 |
><password> |
添加密码,例如:>mypass;此指令会清除 nopass 标志 |
<<password> |
移除指定密码 |
nopass |
移除所有密码,且任何密码都可登录。如果用于 default 用户,则新连接无需 AUTH 即自动登录为 default |
resetpass |
清空所有密码,并移除 nopass 状态。此后没有密码将无法认证 |
reset |
重置所有设置:包括 resetpass、resetkeys、resetchannels、allchannels(如果开启 acl-pubsub-default)、off、clearseletors、-@all |
(<options>) |
创建一个新的 selector(选择器),括号内为该 selector 的独立权限规则 |
clearselectors |
删除所有 selector,但不会影响根权限(直接赋给用户的权限) |
通过 ACL 命令

ACL SETUSER
-
创建/修改用户
1 | # 关闭 default 用户 |
-
可以看的出来,
ACL SETUSER后面的命令格式与直接编辑users.acl文件是一样的 -
这里要注意
ACL SETUSER即可以创建用户,也可以修改用户,当用户不存在时创建用户,当用户存在时修改用户,修改用户时并不会覆盖旧用户,而是会将权限进行合并,比如:
1 | # 第一次执行 |
-
运行后的结果
1 | "user testuser on sanitize-payload #5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 ~* resetchannels -@all +@read +ping +info +client +config|get" |
修改用户权限
-
重置权限
1 | # 重置所有权限 |
-
取消密码,但保留权限
1 | ACL SETUSER testuser nopass |
-
去除所有频道
1 | ACL SETUSER testuser resetchannels |
-
去除所有
selectors,关于selectors后面会详细介绍
1 | ACL SETUSER testuser clearselectors |
ACL LIST
-
可以通过如下命令查看当前 Redis 中所有的用户
1 | ACL LIST |
-
这里显示的并不是设置权限时的命令格式,而是经过翻译后的命令格式
1 | user: 固定前缀 |
ACL LOAD
-
当通过 ACL SETUSER 创建用户时,可以通过如下命令将其保存到
users.acl文件中
1 | ACL SAVE |
-
此时保存的文件内容就是
ACL LIST命令的输出
ACL SAVE
-
当修改了
users.acl文件后,可以通过如下命令将其重新加载到 Redis 中
1 | ACL LOAD |
ACL USERS
-
列出所有已创建的用户
1 | ACL USERS |
ACL GETUSER
-
获取指定用户的权限信息
1 | ACL GETUSER appuser |
selectors(选择器规则)
-
这里看到最后有一个
selectors,这个是Redis 7.0 引入的一个新能力,它允许一个用户同时拥有多套不同的 ACL 规则,而不是只能有一套规则。 -
以前 = 一个用户一条规则
1 | # 根权限(全局规则) |
-
现在 = 一个用户可以有多个“权限分身”
1 | # 选择器规则 |
-
如果一个用户同时拥有 根权限规则 和 选择器规则,则 选择器规则 优先级更高。
ACL DELUSER
-
删除一个用户
1 | ACL DELUSER 用户名 |
ACL WHOAMI
-
获取当前登录的用户名
1 | ACL WHOAMI |
ACL CAT
-
获取所有权限类别
-
前面我们在为用户授权时介绍过,
@后面跟的是一个权限类别,比如 @all、@dangerous,你可以理解为其是一组权限(命令)的集合。 -
ACL CAT命令可以获取所有权限类别,然后你可以根据需要选择需要的权限类别。
1 | # 获取所有权限类别 |
-
这里有一个特殊的权限类别
@all并不在列出的权限类别中,其表示所有命令。
ACL DRYRUN
-
ACL DRYRUN命令可以模拟执行命令,并返回模拟结果,并不是真的执行命令。 -
Redis 7.0.0 新增。
1 | > ACL SETUSER VIRGINIA +SET ~* |
ACL LOG
-
ACL LOG命令可以查看 ACL 命令执行日志。 -
它记录了 ACL(访问控制)相关的事件,也就是用户在操作被拒绝或触发 ACL 规则时的行为记录。
1 | ACL LOG # 查看默认最新的 ACL 日志条目 |
-
日志格式
1 | 1) "count" => 1 |
| 字段 | 含义 |
|---|---|
count |
触发该日志的次数。比如同一事件触发 1 次就是 1 |
reason |
日志触发的原因,通常是 command 表示某个命令被执行或被 ACL 检查 |
context |
执行命令的上下文,toplevel 表示直接在客户端执行 |
object |
触发事件的对象,例如 acl|log表示执行了ACL LOG 命令,acl|list表示执行了ACL LIST |
username |
触发事件的用户 |
age-seconds |
事件距离当前的时间(秒),越大表示越久远 |
client-info |
客户端详细信息,包括客户端 ID、IP 地址、端口、本地地址、文件描述符、客户端名称、DB、执行命令等 |
entry-id |
日志条目 ID |
timestamp-created |
日志创建时间(毫秒) |
timestamp-last-updated |
日志最后更新时间(毫秒) |
ACL GENPASS
-
生成一个随机的 ACL 密码
-
生成复杂密码的工具有很多,没必要用这玩意。
-
该命令的输出是二进制字符串的十六进制表示形式。默认情况下,它会生成 256 位(即 64 个十六进制字符)。用户可以通过提供一个参数来指定生成的位数,范围从 1 到 1024 位,以改变输出长度。需要注意的是,所提供的位数总是会向上取整到 4 的倍数。例如,如果请求生成 1 位密码,实际上会生成 4 位,并以 单个十六进制字符的形式输出。
1 | # 默认64个十六进制字符,相当于 ACL GENPASS 256 |