美文网首页redis
Redis 7 中的用户权限管理功能

Redis 7 中的用户权限管理功能

作者: 阿土伯已经不是我 | 来源:发表于2022-06-08 23:28 被阅读0次

    早期 redis 权限管理功能

    在早期 redis 的权限管理非常弱,还发生过大规模的生产系统的 redis 暴露在公网上,无密码保护,被人将数据加密后进行勒索的事件。后来即时加上了密码保护,也仅仅只是一个是否允许连接的控制,不能分用户,分权限,也一直这么用到现在。前些天看到 redis 7 发布,里面提到升级了新的 ACL 功能,赶紧看了一下,发现有一定的改善,但是还是不太够。

    旧版本兼容

    如果还按照老版本进行配置,那么新版的 redis 还是能够直接通过密码字符串来连接,以便和旧版本兼容。通过执行命令 ACL LIST 可以看出系统中有一个名称叫 default 的用户。默认情况下只输入密码就是指通过这个用户来连接 redis 。

    127.0.0.1:37382> acl LIST
    1) "user default on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* &* +@all"
    

    新版的用户管理

    增加用户

    我们增加一个拥有全部权限的 admin 用户。

    127.0.0.1:37382> ACL SETUSER admin on >Taf&VFIGHlyW*!4iKq#F*#WsYizHkA# ~* +@all
    OK
    127.0.0.1:37382> ACL LIST
    1) "user admin on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* resetchannels +@all"
    2) "user default on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* &* +@all"
    127.0.0.1:37382> 
    

    这个命令各个部分的解释如下:

    1. ACL SETUSER 是用来进行用户管理的命令,后面是命令的参数
    2. admin 是要设置的用户的登录名称
    3. on 是指设置用户的状态 。on 表示可用状态,off 表示不可用状态
    4. Taf&VFIGHlyW!4iKq#F#WsYizHkA# 是要设置的用户的密码
    5. ~* 是一个正则表达式,用来指明用户可以对哪些 key 进行访问。这里指明对所有的key都可以访问。这个表达式可以是多个
    6. +@all 是对用户执行命令权限的设置。这里是指的对所有命令都有权限执行

    通过 ACL LIST 命令可以查看当前系统中用户的列表信息。这里可以看到除了 default 用户,新增加了一个 admin 的用户

    修改用户

    ACL SETUSER 命令可以针对一个用户多次执行。第一次执行增加用户,后续执行的时候就是对用户进行修改了。例如我们新建一个 atu 的账号,并渐次完善相关设置

    127.0.0.1:37382> ACL SETUSER atu
    OK
    127.0.0.1:37382> ACL LIST
    1) "user admin on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* resetchannels +@all"
    2) "user atu off resetchannels -@all"
    3) "user default on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* &* +@all"
    127.0.0.1:37382> 
    

    这个命令增加了一个 atu 用户,没有设置其他任何信息。通过 ACL LIST 命令查看,可以看到这个用户为不可用状态(off),并且没有任何权限(-@all)

    在另一个终端通过 auth 命令进行该用户鉴权,提示如下

    127.0.0.1:37382> AUTH atu
    (error) WRONGPASS invalid username-password pair or user is disabled.
    127.0.0.1:37382> 
    

    现在我们将该用户设置为可以状态并为用户设置密码 123456

    127.0.0.1:37382> ACL SETUSER atu >123456
    OK
    127.0.0.1:37382> ACL LIST
    1) "user admin on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* resetchannels +@all"
    2) "user atu on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 resetchannels -@all"
    3) "user default on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* &* +@all"
    

    在另一个终端用 atu 用户进行连接成功

    127.0.0.1:37382> auth atu 123456
    OK
    127.0.0.1:37382> get name
    (error) NOPERM this user has no permissions to run the 'get' command
    127.0.0.1:37382> 
    

    但是我们使用 get 命令获取一个 key 的值的时候提示没有权限,所以我们可以通过下面的操作为这个用户增加 get 命令的权限

    127.0.0.1:37382> ACL SETUSER atu +get
    OK
    127.0.0.1:37382> ACL LIST
    1) "user admin on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* resetchannels +@all"
    2) "user atu on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 resetchannels -@all +get"
    3) "user default on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* &* +@all"
    

    但是,当我们在另一个终端用这个 atu 用户获取一个 key 的值的时候失败了。显示如下:

    127.0.0.1:37382> get name
    (error) NOPERM this user has no permissions to access one of the keys used as arguments
    

    这提示用户没有获取 name key 值的权限。那么我们为增加所有 key 值的访问权限。

    127.0.0.1:37382> ACL SETUSER atu ~*
    OK
    127.0.0.1:37382> ACL LIST
    1) "user admin on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* resetchannels +@all"
    2) "user atu on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~* resetchannels -@all +get"
    3) "user default on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* &* +@all"
    

    这样用 atu 用户访问 name key 值就可以了。当然,还是不能设定 key 的值。

    127.0.0.1:37382> get name
    "yanggch"
    127.0.0.1:37382> set age 10
    (error) NOPERM this user has no permissions to run the 'set' command
    

    刚才那样让用户有所有 key 的存储权限显然不太合适,需要让制定的用户对某一些 key 有访问的权限。例如我们想让 atu 这个用对以 cached:开头的这些 key 有访问权限,我们就可以为这个用户设定这个权限。

    127.0.0.1:37382> ACL SETUSER atu resetkeys ~cached:*
    OK
    127.0.0.1:37382> ACL SETUSER atu ~shop:*
    OK
    127.0.0.1:37382> ACL LIST
    1) "user admin on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* resetchannels +@all"
    2) "user atu on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~cached:* ~shop:* resetchannels -@all +get"
    3) "user default on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* &* +@all"
    127.0.0.1:37382> set cached:1001 welcome
    OK
    

    这里有一个关键字 resetkeys 表示覆盖设置,因为原来有所有 key 的权限,现在加一个 ~cache 的权限无法生效,所以有所有 key 访问权限的时候必须要加 resetkeys 关键字将所有 key 权限取消掉。不加 resetkeys 关键字的时候,则是追加模式。

    这个时候再用 atu 访问 name 和 cached:1001 。结果如下:

    127.0.0.1:37382> get name
    (error) NOPERM this user has no permissions to access one of the keys used as arguments
    127.0.0.1:37382> get cached:1001
    "welcome"
    127.0.0.1:37382> 
    

    这种带前缀的 key 的设计方法是 redis 中常用的一种方法。前缀可以起到类似数据表的作用。我们通过设置用户能够访问的key的前缀的权限,达到了类似数据库中分库分表设置权限的效果。

    对应命令权限则是通过 + 和 - 两个操作来处理,+ 表示增加某个命令的权限,- 表示取消某个命令的权限。@all 则是特殊的标识,标识所有命令。一般情况下,我们是让用户拥有所有的redis 命令,然后将一些敏感命令权限取消的方式来设置用户的命令权限。这样设置比较简单。例如比较危险的 flushdb 和 flushall 这两个删除所有数据的命令,我们一般都不让普通用户使用。这里将 atu 这个用户设置为拥有所有命令权限,但是取消 flushdb 和 flushall 这两个命令的权限,做法如下:

    127.0.0.1:37382> ACL SETUSER atu +@all
    OK
    127.0.0.1:37382> ACL SETUSER atu -flushdb -flushall
    OK
    127.0.0.1:37382> ACL LIST
    1) "user admin on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* resetchannels +@all"
    2) "user atu on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~cached:* ~shop:* resetchannels +@all -flushall -flushdb"
    3) "user default on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* &* +@all"
    

    这样就不用担心 atu 用户删库跑路了。

    启用外部 ACL 文件

    上面在命令行中设置的用户权限,不能持久化,redis 重启后就失效了。redis 还采用了一种外部 acl 文件的方式。找到 redis 配置文件中 如下部分并将注释取消掉,设置正确的外部 acl 文件名称。

    # Using an external ACL file
    #
    # Instead of configuring users here in this file, it is possible to use
    # a stand-alone file just listing users. The two methods cannot be mixed:
    # if you configure users here and at the same time you activate the external
    # ACL file, the server will refuse to start.
    #
    # The format of the external ACL user file is exactly the same as the
    # format that is used inside redis.conf to describe users.
    #
    aclfile /data/redis7/users.acl
    

    设置外部的 acl 文件为 /data/redis7/users.acl。大家根据自己的环境修改对应的路径并建立一个空的 users.acl 文件。然后将上章节中建立的 admin 用户的配置信息拷贝到改文件中。

    user admin on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* resetchannels +@all
    

    然后,重启启动 redis 即可。现在可以用用户 admin 和对应的密码来连接redis 了

    [root@hecs-99107 bin]# ./redis-cli -p 37382
    127.0.0.1:37382> auth admin Taf&VFIGHlyW*!4iKq#F*#WsYizHkA#
    OK
    127.0.0.1:37382> ACL LIST
    1) "user admin on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* resetchannels +@all"
    

    注意:重启后不带用户,直接输入默认用户密码的连接方式就失效了。
    我们再增加普通的 atu 用户,并且执行 ACL SAVE 命令,最新的用户配置信息就保持到 users.acl 文件中了。

    127.0.0.1:37382> ACL SETUSER atu on >123456 ~cached:* ~shop:* +@all -flushdb -flushall
    OK
    127.0.0.1:37382> ACL LIST
    1) "user admin on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* resetchannels +@all"
    2) "user atu on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~cached:* ~shop:* resetchannels +@all -flushdb -flushall"
    127.0.0.1:37382> ACL SAVE
    OK
    

    查看一下 users.acl 文件,发现多了一行配置

    [root@hecs-99107 redis7]# vi users.acl.bak 
    user admin on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* resetchannels +@all
    user atu on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~cached:* ~shop:* resetchannels +@all -flushdb -flushall
    

    如果手工在 users.acl 中增加一行配置如下

    user atu2 on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~cached:* ~shop:* resetchannels +@all -flushdb -flushall
    

    就增加了一个配置和 atu 一模一样,登录名称为 atu2 的用户。但是这个时候如果 redis 没有重启,这个新配置是不生效的,可以执行 ACL LOAD 命令重新载入最新的 acl 配置信息。

    127.0.0.1:37382> ACL LIST
    1) "user admin on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* resetchannels +@all"
    2) "user atu on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~cached:* ~shop:* resetchannels +@all -flushdb -flushall"
    127.0.0.1:37382> ACL LOAD
    OK
    127.0.0.1:37382> ACL LIST
    1) "user admin on #eb1c66c230df28518559872a792755e1bd7558cb35d58ae9c52689b3dc9ef335 ~* resetchannels +@all"
    2) "user atu on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~cached:* ~shop:* resetchannels +@all -flushdb -flushall"
    3) "user atu2 on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~cached:* ~shop:* resetchannels +@all -flushdb -flushall"
    

    后记

    redis 新的用户管理方面的内容就先聊到这里。其中 key 的配置因为支持正则表达式,所以还能给出各种不同的表达式,这个由正则表达式的达人们来去实验吧。
    不知道大家学废了没有呢。

    相关文章

      网友评论

        本文标题:Redis 7 中的用户权限管理功能

        本文链接:https://www.haomeiwen.com/subject/ovwumrtx.html