Redis系列(十一)、Redis6新特性之ACL安全策略(用户权限管理)

目录

介绍

配置文件模式

conf文件模式

外部ACLFILE模式 

对比conf和aclfile模式

命令行模式

介绍 

ACL规则

启用和禁用用户

允许和禁止调用命令

允许或禁止访问某些Key

为用户配置有效密码

ACL HELP

ACL LIST

ACL USERS

ACL WHOAMI

ACL CAT

ACL SETUSER

ACL GETUSER

ACL DELUSER

ACL SAVE

ACL LOAD

ACL GENPASS

ACL LOG

AUTH

小结


好消息!好消息!Redis出权限管理功能了!你还不来看看吗?

自从Redis6.0以来,大家呼吁了很久的权限管理功能(ACL[access control list 访问控制列表])终于发布了,通过此功能,我们可以设置不同的用户并对他们授权命令或数据权限。这样我们可以避免有些用户的误操作导致数据丢失或避免数据泄露的安全风险。


Redis系列文章:

Redis系列(一)、CentOS7下安装Redis6.0.3稳定版

Redis系列(二)、数据类型之字符串String 

Redis系列(三)、数据类型之哈希Hash

Redis系列(四)、数据类型之列表List

Redis系列(五)、数据类型之无序集合Set

Redis系列(六)、数据类型之有序集合ZSet(sorted_set)

Redis系列(七)、常用key命令

Redis系列(八)、常用服务器命令 

Redis系列(九)、Redis的“事务”及Lua脚本操作

Redis系列(十)、详解Redis持久化方式AOF、RDB以及混合持久化


介绍

在Redis6之前的版本,我们只能使用requirepass参数给default用户配置登录密码,同一个redis集群的所有开发都共享default用户,难免会出现误操作把别人的key删掉或者数据泄露的情况,那之前我们也可以使用rename command的方式给一些危险函数重命名或禁用,但是这样也防止不了自己的key被其他人访问。

因此Redis6版本推出了ACL(Access Control List)访问控制权限的功能,基于此功能,我们可以设置多个用户,并且给每个用户单独设置命令权限和数据权限。 为了保证向下兼容,Redis6保留了default用户和使用requirepass的方式给default用户设置密码,默认情况下default用户拥有Redis最大权限,我们使用redis-cli连接时如果没有指定用户名,用户也是默认default。鼓掌!

我们可以在配置文件中或者命令行中设置ACL,如果使用配置config文件的话需要重启服务,使用配置aclfile文件或者命令行授权的话无需重启Redis服务但需要及时将权限持久化到磁盘,否则下次重启的时候无法恢复该权限。 

官网:https://redis.io/topics/acl

配置文件模式

配置ACL的方式有两种,一种是在config文件中直接配置,另一种是在外部aclfile中配置。配置的命令是一样的,但是两种方式只能选择其中一种,我们之前使用requirepass给default用户设置密码 默认就是使用config的方式,执行config rewrite重写配置后会自动在config文件最下面新增一行记录配置default的密码和权限:

conf文件模式

使用redis.conf文件配置default和其他用户的ACL权限

1.在config文件中配置default用户的密码
requirepass 123456

2.在config文件中添加DSL命令配置用户ACL权限
【使用方式在下文】

3.在config文件中注释aclfile的路径配置(默认是注释的)
#aclfile /opt/app/redis6/users.acl

4.重启redis服务
systemctl restart redis

因此我们可以直接在config配置文件中使用上面default用户ACL这行DSL命令设置用户权限,或者我们也可以配置外部aclfile配置权限。

配置aclfile需要先将config中配置的DSL注释或删除,因为Redis不允许两种ACL管理方式同时使用,否则在启动redis的时候会报下面的错误:

# Configuring Redis with users defined in redis.conf and at the same setting an ACL file path is invalid. This setup is very likely to lead to configuration errors and security holes, please define either an ACL file or declare users directly in your redis.conf, but not both.

外部ACLFILE模式 

 使用外部aclfile文件配置Default和其他用户的ACL权限

1.注释redis.conf中所有已授权的ACL命令,如:
#user default on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~* +@all

2.在config文件中注释default用户的密码,因为开启aclfile之后,requirepass的密码就失效了:
redis.conf
#requirepass 123456

users.acl
user default on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~* +@all

3.在config文件中配置aclfile的路径,然后创建该文件,否则重启redis服务会报错找不到该文件
aclfile /opt/app/redis6/users.acl
touch /opt/app/redis6/users.acl

4.在外部aclfile文件中添加DSL命令配置用户ACL权限
【使用方式在下文】

5.重启redis服务或使用aclfile load命令加载权限
systemctl restart redis
或
在redis命令行中执行:
aclfile load

开启aclfile之后不再推荐在redis.conf文件中通过requirepass配置default的密码,因为它不再生效,同时开启aclfile之后也不能使用redis-cli -a xxx登陆,必须使用redis-cli --user xxx  --pass yyy来登陆:  

 

对比conf和aclfile模式

 在redis.conf和aclfile模式中配置DSL 官方更推荐使用aclfile,因为如果在redis,conf中配置了权限之后需要重启redis服务才能将配置的权限加载至redis服务中来,但如果使用aclfile模式,可以调用acl load命令将aclfile中配置的ACL权限热加载进环境中,类似于Mysql中的flush privileges。

对比conf和aclfile
  redis.conf users.acl
配置方式 DSL DSL
加载ACL配置 重启Redis服务 ACL LOAD命令
持久化ACL配置 CONFIG REWRITE命令 ACL SAVE命令

命令行模式

介绍 

上面可以看到,我们在配置文件中配置的ACL权限,需要执行ACL LOAD或者重启Redis服务才能生效,事实上我们可以直接在命令行下配置ACL,在命令行模式下配置的权限无需重启服务即可生效。我们也可以在命令行模式下配置ACL并将其持久化到aclfile或者config文件中(这取决于配置文件中选择的是config模式还是外部aclfile模式),一旦将权限持久化到aclfile或cofig文件中,下次重启就会自动加载该权限,如果忘记持久化,一旦服务宕机或重启,该权限就会丢失。

如果使用config模式,将ACL权限持久化到redis.conf文件中使用下面的命令:
config rewrite

如果使用aclfile模式,将ACL权限持久化到users.acl文件中使用下面的命令:
acl save

ACL规则

ACL是使用DSL(Domain specific language)定义的,该DSL描述了用户能够执行的操作。该规则始终从上到下,从左到右应用,因为规则的顺序对于理解用户的实际权限很重要。ACL规则可以在redis.conf文件以及users.acl文件中配置DSL,也可以在命令行中通过ACL命令配置。

启用和禁用用户

  • on:启用用户:可以以该用户身份进行认证。
  • off:禁用用户:不再可以使用此用户进行身份验证,但是已经通过身份验证的连接仍然可以使用。

允许和禁止调用命令

  • +<command>:将命令添加到用户可以调用的命令列表中。
  • -<command>:将命令从用户可以调用的命令列表中移除。
  • +@<category>:允许用户调用 <category> 类别中的所有命令,有效类别为@admin,@set,@sortedset等,可通过调用ACL CAT命令查看完整列表。特殊类别@all表示所有命令,包括当前和未来版本中存在的所有命令。
  • -@<category>:禁止用户调用<category> 类别中的所有命令。
  • +<command>|subcommand:允许使用已禁用命令的特定子命令。
  • allcommands:+@all的别名。包括当前存在的命令以及将来通过模块加载的所有命令。
  • nocommands:-@all的别名,禁止调用所有命令。

允许或禁止访问某些Key

  •  ~<pattern>:添加可以在命令中提及的键模式。例如~** allkeys 允许所有键。
  • resetkeys:使用当前模式覆盖所有允许的模式。如: ~foo:* ~bar:*  resetkeys ~objects:* ,客户端只能访问匹配 object:* 模式的 KEY。

为用户配置有效密码

  • ><password>:将此密码添加到用户的有效密码列表中。例如,>mypass将“mypass”添加到有效密码列表中。该命令会清除用户的nopass标记。每个用户可以有任意数量的有效密码。
  • <<password>:从有效密码列表中删除此密码。若该用户的有效密码列表中没有此密码则会返回错误信息。
  • #<hash>:将此SHA-256哈希值添加到用户的有效密码列表中。该哈希值将与为ACL用户输入的密码的哈希值进行比较。允许用户将哈希存储在users.acl文件中,而不是存储明文密码。仅接受SHA-256哈希值,因为密码哈希必须为64个字符且小写的十六进制字符。
  • !<hash>:从有效密码列表中删除该哈希值。当不知道哈希值对应的明文是什么时很有用。
  • nopass:移除该用户已设置的所有密码,并将该用户标记为nopass无密码状态:任何密码都可以登录。resetpass命令可以清除nopass这种状态。
  • resetpass:情况该用户的所有密码列表。而且移除nopass状态。resetpass之后用户没有关联的密码同时也无法使用无密码登录,因此resetpass之后必须添加密码或改为nopass状态才能正常登录。
  • reset:重置用户状态为初始状态。执行以下操作resetpass,resetkeys,off,-@all。

ACL HELP

使用下面的命令查看help文档:

acl help

ACL LIST

我们可以使用ACL LIST命令来查看当前活动的ACL,默认情况下,有一个“default”用户:

127.0.0.1:6379> acl list
1) "user default on nopass ~* +@all"

其中user为关键词,default为用户名,后面的内容为ACL规则描述,on表示活跃的,nopass表示无密码, ~* 表示所有key,+@all表示所有命令。所以上面的命令表示活跃用户default无密码且可以访问所有命令以及所有数据。

ACL USERS

返回所有用户名:

acl users

ACL WHOAMI

返回当前用户名:

acl whoami

 

ACL CAT

查看命令类别,用于授权:

ACL CAT:显示所有的命令类别 。
ACL CAT <category>:显示所有指定类别下的所有命令。 

ACL SETUSER

使用下面的命令创建或修改用户属性,username区分大小写

#username区分大小写
#若用户不存在则按默认规则创建用户,若存在则修改用户属性
SETUSER <username> [attribs ...]

#若用户不存在,则按默认规则创建用户。若用户存在则该命令不做任何操作。
ACL SETUSER <username> 

#若用户不存在,则按默认规则创建用户,并为其增加<rules>。若用户存在则在已有规则上增加 <rules>。
ACL SETUSER <username> <rules> 

默认规则下新增的用户处于非活跃状态,且没有密码,同时也没有任何命令和key的权限: 

 

例:使用下面的命令新增用户/修改用户的权限:

#on为活跃状态,密码为wyk123456,允许对所有csdn开头的key使用get和set命令
ACL SETUSER wyk on >wyk123456 ~csdn* +get +set

#为wyk用户新增一个可用密码csdn8888
ACL SETUSER wyk on >csdn8888

#为wyk用户新增list类别下所有命令的权限
ACL SETUSER wyk on +@list

 

 

ACL GETUSER

使用下面的命令查看用户的ACL权限:

#查看用户的ACL权限
acl getuser <username>

ACL DELUSER

删除指定的用户:

#删除指定的用户
acl deluser <username>

ACL SAVE

前面提到过,我们可以使用acl save命令将当前服务器中的ACL权限持久化到aclfile中,如果没持久化就关闭redis服务,那些ACL权限就会丢失,因此我们每次授权之后一定要记得ACL SAVE将ACL权限持久化到aclfile中:

#将acl权限持久化到磁盘的aclfile中
acl save

#如果使用redis.conf配置ACL,则使用config rewrite命令将ACL持久化到redis.conf中
config rewrite

 

ACL LOAD

我们也可以直接在aclfile中修改或新增ACL权限,修改之后不会立刻生效,我们可以在redis命令行中执行acl load将该aclfile中的权限加载至redis服务中:

#将aclfile中的权限加载至redis服务中
acl load

ACL GENPASS

随机返回sha256密码,我们可以直接使用该密文配置ACL密码:

#随机返回一个256bit的32字节的伪随机字符串,并将其转换为64字节的字母+数字组合字符串
acl genpass

#可指定位数
acl genpass 32
acl genpass 64

 

ACL LOG

查看ACL安全日志:

acl log

AUTH

使用auth命令切换用户:

AUTH <username> <password>

小结

由于Redis是高性能的数据库,正常情况下每秒可以接收百万级别的请求,因此我们的用户密码一定要是非常复杂的组合,否则很容易就会被暴利跑字典给破解了,不管怎么说,这次Redis6版本带来的新特性ACL权限控制也是解决了我们很大的痛点,终于可以权限隔离了!

希望本文对你有帮助,请点个赞鼓励一下作者吧~ 谢谢!

猜你喜欢

转载自blog.csdn.net/wsdc0521/article/details/106765856