Redis ACL及兼容低版本redis server端分析

简介

在 Redis 6.0 中引入了 ACL(Access Control List) 的支持,在此前的版本中 Redis 中是没有用户的概念的,也就不能根据username来精确的划分其权限,Redis client端也就没有username这个参数。redis 6.0 开始支持用户,可以给每个用户分配不同的权限来控制权限。目前redis常用的client——Jedis和Lettuce也对其做了支持。当然此次更新redis的服务端和客户端都是向前兼容的。

Redis服务端

开启ACL:

  1. 在命令行通过 ACL 命令配置
  2. 开启 Redis 配置文件中开启 aclfile 配置项,通过配置文件的方式加载

Auth命令:

首先最明显的就是此次升级对auth命令做了扩展,从之前的

AUTH 

扩展到了

AUTH  

为了兼容之前的版本,那么auth 等价于auth default 

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

同 ACL LIST 作用类似。ACL GETUSER 用来获取指定用户的 ACL 状态信息

ACL USERS

查看 ACL 的所有用户

ACL WHOAMI

查看当前操作的用户

ACL CAT

显示所有的 ACL 类别
ACL CAT <类别> 显示指定类别中所有的 Redis 命令

删除用户:ACL DELUSER

随机生成密码:ACL GENPASS 该命令默认创建一个 256 bit 的 32 字节的伪随机字符串,并将其转换为 64 字节的字母+数字的字符串。如有有参数,则使用指定的位数长度

权限配置

1.使用 ACL 命令

命令 含义
+ 将命令添加到用户可以调用的命令列表中
- 将命令移至用户可以调用的命令列表中
+@ 添加该类别中要由用户调用的所有命令,有效类别为@ admin,@ set,@ sortedset等
-@ 与上面的命令相对,移除一个饿类别的所有命令
+|subcommand 允许使用本来禁用的命令中的特定子命令。请注意,不允许使用这种形式的负数,只能以“ +”开头。如果命令在整体上已经处于活动状态,则此ACL将导致错误。
allcommands +@ all的别名(加载所有命令)
nocommands -@  all的别名(移除所有命令)
~ 添加可以在命令中提及的Key模式。例如~*允许所有键。
allkeys ~*的别名
resetkeys 刷新允许的Key模式列表,例如,ACL~foo:* ~bar:* resetkeys ~objects:*将导致客户端只能访问与模式匹配的密钥objects:*
> 将此密码添加到用户的有效密码列表中
< 从有效密码列表中删除此密码
# 将此SHA-256哈希值添加到用户的有效密码列表中
! 从有效密码列表中删除该哈希值
nopass 删除了用户设置的所有密码,并且该用户被标记为不需要密码:这意味着每个密码都将对该用户起作用
resetpass 刷新允许的密码列表,而且删除nopass

2.使用 ACL SETUSER命令

ACL SETUSER :则按默认规则创建用户。用户存在,则该命令不执行任何操作。

  • 处于关闭状态
  • 无法执行任何命令
  • 没有匹配的访问 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配置文件

  1. 直接配置在redis.conf中
  2. 使用外部的acl配置文件

外部配置文件的语法和redis.conf相同,但是外部配置的方式更加的灵活,所以推荐使用第二种方式

配置语法:

user  ... 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)
    }
}

 

你可能感兴趣的:(java,Redis,kotiln,redis)