ACLs 权限控制
Redis 6开始支持ACL,该功能通过限制对命令和key的访问来提高安全性。ACL的工作方式是在连接之后,要求客户端进行身份验证(用户名和有效密码);如果身份验证阶段成功,则连接与指定用户关联,并且该用户具有限制。 在默认配置中,Redis 6的工作方式与Redis的旧版本完全相同,每个新连接都能够调用每个可能的命令并访问每个键,因此ACL功能与旧版本向后兼容。客户和应用程序。依旧使用requirepass配置密码的,但现在只是为默认用户设置密码。
4.1 ACL使用
1) ACL <subcommand> arg arg ... arg. Subcommands are:
2) LOAD -- Reload users from the ACL file.
3) SAVE -- Save the current config to the ACL file.
4) LIST -- Show user details in config file format.
5) USERS -- List all the registered usernames.
6) SETUSER <username> [attribs ...] -- Create or modify a user.
7) GETUSER <username> -- Get the user details.
8) DELUSER <username> [...] -- Delete a list of users.
9) CAT -- List available categories.
10) CAT <category> -- List commands inside category.
11) GENPASS [<bits>] -- Generate a secure user password.
12) WHOAMI -- Return the current connection username.
13) LOG [<count> | RESET] -- Show the ACL log entries.
Redis6中auth命令在Redis 6中进行了扩展,因此现在可以在两个参数的形式中使用它:
#before Redis 6
AUTH <password>
#Redis 6
AUTH <username> <password>
默认情况下,有一个用户定义,称为default
。可以使用ACL LIST命令来查看,默认配置的Redis实例的配置是:
#无密码
127.0.0.1:6379> ACL LIST
1) "user default on nopass ~* +@all"
#有密码
127.0.0.1:6379> ACL LIST
1) "user default on #ce306e0ee195cc817620c86d7b74126d0d66c077b66f66c10f1728cf34a214d3
127.0.0.1:6379> ACL WHOAMI
"default"
127.0.0.1:6379> ACL USERS
1) "default"
每行的开头都是“ user”,后面跟用户名,on
表示用户是启用的,否则是禁用的。nopass
表示无密码,否则表示有密码认证。(~*
)表示能够访问所有的key,+ @ all
表示能够调用所有可能的命令。
4.2 ACL规则
启用和禁止用户
on
:启用用户:可以以该用户身份进行认证。off
:禁用用户:不再可以与此用户进行身份验证,但是已经过身份验证的连接仍然可以使用。如果默认用户标记为off,则无论默认用户配置如何,新连接都将开始不进行身份验证,并且要求用户使用AUTH选项发送AUTH以进行身份验证。
允许和禁止命令
+<command>
:将命令添加到用户可以调用的命令列表中。-<command>
:将命令从用户可以调用的命令列表中删除。+@<category>
:添加该类别中要由用户调用的所有命令,有效类别为@ admin,@ set,@ sortedset等,通过调用ACL CAT命令查看完整列表。特殊类别@all表示所有命令,包括当前在服务器中存在的命令,以及将来将通过模块加载的命令。127.0.0.1:6379> ACL CAT 1) "keyspace" 2) "read" 3) "write" 4) "set" 5) "sortedset" 6) "list" 7) "hash" 8) "string" 9) "bitmap" 10) "hyperloglog" 11) "geo" 12) "stream" 13) "pubsub" 14) "admin" 15) "fast" 16) "slow" 17) "blocking" 18) "dangerous" 19) "connection" 20) "transaction" 21) "scripting"
-@<category>
:从客户端可以调用的命令列表中删除命令。+<command>|subcommand
:允许使用本来禁用的命令的特定子命令。该语法不允许使用-<command>|subcommand
,例如-DEBUG|SEGFAULT
,只能以“ +”开头的加法运算符。如果命令整体上已处于活动状态,则此ACL将导致错误。allcommands
:+ @ all
的别名。nocommands
:-@ all
的别名。
允许或禁止访问某些Key
- ~:添加可以在命令中提及的键模式。例如~和 allkeys 允许所有键。
- resetkeys:使用当前模式覆盖所有允许的模式。如: ~foo: ~bar: resetkeys ~objects: ,客户端只能访问匹配 object: 模式的 KEY。
为用户配置有效密码
- :将此密码添加到用户的有效密码列表中。例如,>mypass将“mypass”添加到有效密码列表中。该命令会清除用户的nopass标记。每个用户可以有任意数量的有效密码。
- <:从有效密码列表中删除此密码。若该用户的有效密码列表中没有此密码则会返回错误信息。
- :将此SHA-256哈希值添加到用户的有效密码列表中。该哈希值将与为ACL用户输入的密码的哈希值进行比较。允许用户将哈希存储在users.acl文件中,而不是存储明文密码。仅接受SHA-256哈希值,因为密码哈希必须为64个字符且小写的十六进制字符。
- !:从有效密码列表中删除该哈希值。当不知道哈希值对应的明文是什么时很有用。
- nopass:移除该用户已设置的所有密码,并将该用户标记为nopass无密码状态:任何密码都可以登录。resetpass命令可以清除nopass这种状态。
- resetpass:情况该用户的所有密码列表。而且移除nopass状态。resetpass之后用户没有关联的密码同时也无法使用无密码登录,因此resetpass之后必须添加密码或改为nopass状态才能正常登录。
- reset:重置用户状态为初始状态。执行以下操作resetpass,resetkeys,off,-@all。
4.3 创建和编辑用户
127.0.0.1:6379> ACL SETUSER zijie
OK
`SETUSER`命令采用用户名和ACL规则列表以应用于用户。但是在上面的示例中,没有指定任何规则。如果用户不存在,这将使用默认属性来创建用户。如果用户已经存在,则上面的命令将不执行任何操作。
默认的用户状态:
127.0.0.1:6379> acl list
1) "user default on #ce306e0ee195cc817620c86d7b74126d0d66c077b66f66c10f1728cf34a214d3 ~* +@all"
2) "user zijie off -@all"
刚创建的用户zijie
是:
处于禁用状态,AUTH不起作用。
无法访问任何命令。
无法访问任何key。
没有设置密码。
127.0.0.1:6379> ACL SETUSER zijie2 on >123 ~* +get OK 127.0.0.1:6379> acl list 1) "user default on #ce306e0ee195cc817620c86d7b74126d0d66c077b66f66c10f1728cf34a214d3 ~* +@all" 2) "user zijie off -@all" 3) "user zijie2 on #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 ~cached:* -@all +get" 127.0.0.1:6379> ACL SAVE OK
用户可以执行某些操作,但是会拒绝执行其他操作,权限动态生效:
127.0.0.1:6379> auth zijie2 123
OK
127.0.0.1:6379> get name
"zijie"
127.0.0.1:6379> set name:2 a
(error) NOPERM this user has no permissions to run the 'set' command or its subcommand
#ACL LIST 查看用户配置
127.0.0.1:6379> ACL LIST
1) "user default on #ce306e0ee195cc817620c86d7b74126d0d66c077b66f66c10f1728cf34a214d3 ~* +@all"
2) "user zijie off -@all"
3) "user zijie2 on #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 ~* -@all +get"
#用户名区分大小写,ACL GETUSER 易读性高于ACL LIST
127.0.0.1:6379> ACL GETUSER zijie2
1) "flags"
2) 1) "on"
2) "allkeys"
3) "passwords"
4) 1) "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
5) "commands"
6) "-@all +get"
7) "keys"
8) 1) "*"
#使用RESP3易读性更高
127.0.0.1:6379> ACL GETUSER zijie2
1# "flags" => 1~ "on"
2~ "allkeys"
2# "passwords" => 1) "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
3# "commands" => "-@all +get"
4# "keys" => 1) "*"
使用另一个ACL SETUSER命令向用户添加多个模式:
127.0.0.1:6379> ACL SETUSER zijie3 on >123 ~zijie* +get
OK
127.0.0.1:6379> ACL SETUSER zijie3 on >123 ~zijie* +set
OK
127.0.0.1:6379> ACL SETUSER zijie3 on >123 ~zijie* +@read
OK
127.0.0.1:6379> ACL LIST
1) "user default on #ce306e0ee195cc817620c86d7b74126d0d66c077b66f66c10f1728cf34a214d3 ~* +@all"
2) "user zijie off -@all"
3) "user zijie2 on #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 ~* -@all +get"
4) "user zijie3 on #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 ~zijie* ~name* ~xx* -@all +@read +@hash +@bitmap +@geo -bitfield -hmset +set -geoadd -hincrby -hset -hincrbyfloat -georadiusbymember -hdel -hsetnx -bitop -georadius -setbit"
#删除用户
ACL DELUSER zijie3
4.4 命令类别
ACL有类似”资源组“的概念,给一类命令一个别名,来达到快速授权。
127.0.0.1:6379> acl cat
1) "keyspace"
2) "read"
3) "write"
4) "set"
5) "sortedset"
6) "list"
7) "hash"
8) "string"
9) "bitmap"
10) "hyperloglog"
11) "geo"
12) "stream"
13) "pubsub"
14) "admin"
15) "fast"
16) "slow"
17) "blocking"
18) "dangerous"
19) "connection"
20) "transaction"
21) "scripting"
127.0.0.1:6379> acl cat dangerous
1) "flushdb"
2) "sort"
3) "swapdb"
4) "replicaof"
5) "shutdown"
6) "replconf"
7) "keys"
8) "lastsave"
9) "psync"
10) "cluster"
11) "module"
12) "acl"
13) "bgrewriteaof"
14) "info"
15) "debug"
16) "bgsave"
17) "sync"
18) "flushall"
19) "save"
20) "pfdebug"
21) "latency"
22) "role"
23) "slaveof"
24) "migrate"
25) "pfselftest"
26) "config"
27) "monitor"
28) "restore"
29) "slowlog"
30) "restore-asking"
31) "client"
127.0.0.1:6379> ACL SETUSER zijie4 on +@all -@dangerous >123 ~*
OK
127.0.0.1:6379> ACL GETUSER zijie4
1) "flags"
2) 1) "on"
2) "allkeys"
3) "passwords"
4) 1) "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
5) "commands"
6) "+@all -@admin -@dangerous"
7) "keys"
8) 1) "*"
授权子命令
ACL SETUSER zijie5 -client +client|setname +client|getname
4.5 使用外部ACL文件
Redis6因为引入了权限机制,会有不同分工的用户;所以又引入了额外的配置项以及配置文件,通过ACL LOAD/ACL SAVE报错和加载acl文件。
[root@zijie ~]# cat /etc/Redis6.conf | grep acl
aclfile /usr/local/Redis/users.acl
acllog-max-len 128
#Redis6开始密码加密存储
[root@zijie ~]# cat /usr/local/Redis/users.acl
user default on #ce306e0ee195cc817620c86d7b74126d0d66c077b66f66c10f1728cf34a214d3 ~* +@all
user zijie off -@all
user zijie2 on #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 ~* -@all +get
user zijie3 off ~zijie* ~name* -@all
#获取安全密码
127.0.0.1:6379> ACL GENPASS
"c550b646ef8f7f91908628db0d983b4ca061fcf36433baa770ea9ce09da64ef4"
4.6 哨兵和副本的ACL规则
如果不想为Redis副本和Redis Sentinel实例提供对Redis实例的完全访问权限,则以下是一组命令,为了使一切正常工作,必须允许这些命令。 对于Sentinel,允许用户在主实例和副本实例中访问以下命令: Sentinel不需要访问数据库中的任何密钥,因此ACL规则如下(注意:不需要AUTH,因为始终允许使用AUTH):
ACL setuser sentinel-user >somepassword +client +subscribe +publish +ping +info +multi +slaveof +config +client +exec on
Redis副本需要在主实例上将以下命令列入白名单:
- PSYNC,REPLCONF,PING
不需要访问任何密钥,因此这转化为以下规则:
ACL setuser replica-user >somepassword +psync +replconf +ping on
无需将副本配置为允许主服务器能够执行任何命令集:从副本的角度来看,主服务器始终被认证为root用户。
4.7 ACL LOG
记录拒绝的命令,密钥访问和身份验证。
127.0.0.1:6379> acl log
1) 1) "count"
2) (integer) 1
3) "reason"
4) "auth"
5) "context"
6) "toplevel"
7) "object"
8) "auth"
9) "username"
10) "default"
11) "age-seconds"
12) "7.3860000000000001"
13) "client-info"
14) "id=18 addr=127.0.0.1:51882 fd=8 name= age=2 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=32742 obl=0 oll=0 omem=0 events=r cmd=auth user=default"