简介
在 Redis 6.0 中引入了 ACL(Access Control List) 的支持,在此前的版本中 Redis 中是没有用户的概念的,也就不能根据username来精确的划分其权限,Redis client端也就没有username这个参数。redis 6.0 开始支持用户,可以给每个用户分配不同的权限来控制权限。目前redis常用的client——Jedis和Lettuce也对其做了支持。当然此次更新redis的服务端和客户端都是向前兼容的。
Redis服务端
开启ACL:
- 在命令行通过 ACL 命令配置
- 开启 Redis 配置文件中开启 aclfile 配置项,通过配置文件的方式加载
Auth命令:
首先最明显的就是此次升级对auth命令做了扩展,从之前的
AUTH <password>
扩展到了
AUTH <username> <password>
为了兼容之前的版本,那么auth <password>等价于auth default <password>
ACL LIST:查看acl,默认只有一个用户default
127.0.0.1:6379> ACL LIST
1) "user default on nopass ~* +@all"
上面的命令通过将为用户设置的当前ACL转换回其描述中,以与Redis配置文件中使用的格式相同的格式报告用户列表。
参数 | 含义 |
---|---|
user+default | 用户名 |
on | 启用此用户,off为禁用 |
nopass | 用户的密码,napass表示没有设置密码 |
~* | 表示可以访问的Key(正则匹配) |
+@all | 用户的命令权限。‘+’表有的权限,‘-’表没有的权限。 @为命令分类,可以通过 ACL CAT 查询支持的分类。‘all’表所有 |
除此只为还有一些其他的查看user信息的命令:
命令 | 含义 |
---|---|
ACL GETUSER <username> | 同 ACL LIST 作用类似。ACL GETUSER 用来获取指定用户的 ACL 状态信息 |
ACL USERS | 查看 ACL 的所有用户 |
ACL WHOAMI | 查看当前操作的用户 |
ACL CAT | 显示所有的 ACL 类别 |
ACL CAT <类别> | 显示指定类别中所有的 Redis 命令 |
删除用户:ACL DELUSER <username>
随机生成密码:ACL GENPASS <mumber>该命令默认创建一个 256 bit 的 32 字节的伪随机字符串,并将其转换为 64 字节的字母+数字的字符串。如有有参数,则使用指定的位数长度
权限配置
1.使用 ACL 命令
命令 | 含义 |
---|---|
+<command> | 将命令添加到用户可以调用的命令列表中 |
-<command> | 将命令移至用户可以调用的命令列表中 |
+@<category> | 添加该类别中要由用户调用的所有命令,有效类别为@ admin,@ set,@ sortedset等 |
-@<category> | 与上面的命令相对,移除一个饿类别的所有命令 |
+<command>|subcommand | 允许使用本来禁用的命令中的特定子命令。请注意,不允许使用这种形式的负数,只能以“ +”开头。如果命令在整体上已经处于活动状态,则此ACL将导致错误。 |
allcommands | +@ all的别名(加载所有命令) |
nocommands | -@ all的别名(移除所有命令) |
~<pattern> | 添加可以在命令中提及的Key模式。例如~* 允许所有键。 |
allkeys | ~* 的别名 |
resetkeys | 刷新允许的Key模式列表,例如,ACL~foo:* ~bar:* resetkeys ~objects:* 将导致客户端只能访问与模式匹配的密钥objects:* |
><password> | 将此密码添加到用户的有效密码列表中 |
<<password> | 从有效密码列表中删除此密码 |
#<hash> | 将此SHA-256哈希值添加到用户的有效密码列表中 |
!<hash> | 从有效密码列表中删除该哈希值 |
nopass | 删除了用户设置的所有密码,并且该用户被标记为不需要密码:这意味着每个密码都将对该用户起作用 |
resetpass | 刷新允许的密码列表,而且删除nopass |
2.使用 ACL SETUSER命令
ACL SETUSER <USERNAME>:则按默认规则创建用户。用户存在,则该命令不执行任何操作。
- 处于关闭状态
- 无法执行任何命令
- 没有匹配的访问 KEY 的模式
- 没有有效的密码
使用ACL SETUSER一次性建立规则更加完善的用户,例如:
127.0.0.1:6379> ACL SETUSER userTest on >p1pp0 ~cached:* +get
OK
127.0.0.1:6379> ACL GETUSER userTest
1) "flags"
2) 1) "on"
3) "passwords"
4) 1) "2d9c75273d72b32df726fb545c8a4edc719f0a95a6fd993950b10c474ad9c927"
5) "commands"
6) "-@all +get"
7) "keys"
8) 1) "cached:*"
3.使用外部ACL配置文件
- 直接配置在redis.conf中
- 使用外部的acl配置文件
外部配置文件的语法和redis.conf相同,但是外部配置的方式更加的灵活,所以推荐使用第二种方式
配置语法:
user <username> ... acl rules ...
例如:
user userTest +@list +@connection ~jobs:* on >ffa9203c493aa99
当您要使用外部ACL文件时,需要指定名为的配置指令 aclfile:
aclfile /etc/redis/users.acl
当仅在redis.conf 文件内部直接指定几个用户时,可以使用CONFIG REWRITE以便通过重写将新的用户配置存储在文件中。
但是,外部ACL文件功能更强大。您可以执行以下操作:
- 使用
ACL LOAD
重新加载外部 ACL 文件,通常在你手动修改了这个文件,希望 redis 重新加载的时候使用,需要注意的是要确保 acl 文件内容的正确性 - 使用
ACL SAVE
将当前 ACL 配置保存到一个外部文件
后面redis哨兵模式等就不过多的介绍,详细的请参考redis acl官方文档
Redis客户端
redis client比较常用的有Jedis和Lettuce,现在两个client也是对redis6.0的更新做了兼容。之前实现的Redis客户端Jedis,Lettuce和vertx的使用比较及部分源码解析中使用的就是redis6.0更新后的版本实现。而且经过测试,如果redis client是6.0之后的版本,server端是6.0之前的版本,其实都是兼容的。
再如你的redis client使用的是6.0之后的版本,而server分别有6.0之前和6.0之后两个版本,且想都兼容。Jedis也是相同的。
@Test
fun redis5Test() {
val node = RedisURI.builder()
.withHost("127.0.0.1")
.withPort(6379)
.withTimeout(Duration.ofMillis(3000))
// 只需要把authentication的username设成“”就可以兼容redis server6.0之前的版本
.withAuthentication("", "test123")
.build()
val client = RedisClient.create(node)
try {
val con = client.connect()
val a = con.sync().get("123")
println("result is: $a")
} catch (e: Exception) {
println(e)
}
}