众所周知 redis 6.0 两个比较大的特性 一个是多线程IO 一个是ACL。
今天主要讲解下 ACL特性,以及我的一些看法。结尾有对阿里云redis的一些调研彩蛋。哈哈
什么是ACL:
官方定义:ACL 是 Access Control List 缩写,主要是限制特定连接的 特定数据访问权限和特定命令执行。采用不同的user 采用不同的 acl策略来实现,默认值兼容 之前的 auth passwd模式的。
The Redis AUTH command was extended in Redis 6, so now it is possible to use it in the two-arguments form: AUTH <username> <password> When it is used according to the old form, that is: AUTH <password>
127.0.0.1:6379> acl help 1) ACL <subcommand> [<arg> [value] [opt] ...]. Subcommands are: 2) CAT [<category>] 3) List all commands that belong to <category>, or all command categories 4) when no category is specified. 5) DELUSER <username> [<username> ...] 6) Delete a list of users. 7) GETUSER <username> 8) Get the user's details. 9) GENPASS [<bits>] 10) Generate a secure 256-bit user password. The optional `bits` argument can 11) be used to specify a different size. 12) LIST 13) Show users details in config file format. 14) LOAD 15) Reload users from the ACL file. 16) LOG [<count> | RESET] 17) Show the ACL log entries. 18) SAVE 19) Save the current config to the ACL file. 20) SETUSER <username> <attribute> [<attribute> ...] 21) Create or modify a user with the specified attributes. 22) USERS 23) List all the registered usernames. 24) WHOAMI 25) Return the current connection username. 26) HELP 27) Prints this help. 127.0.0.1:6379>
ACL 命令目录
可以看到 通过 acl cat 可以看到不同中类型的
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"
ACL命令详解
通过 setuser ,deluser,getuser
通过 load ,save 可以持久化保存acl状态。
这里主要讲述一下 acl setuser 子命令。
SETUSER [ ...]
比如 acl setuser aliyundev on
127.0.0.1:6379> acl setuser aliyundev on OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "on" 2) "allchannels" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all" 7) "keys" 8) (empty list or set) 9) "channels" 10) 1) "*" 127.0.0.1:6379>
前方高能 请仔细看注释,#号开始的 均为注解。请执行 #之前的部分。
127.0.0.1:6379> acl setuser aliyundev on OK 127.0.0.1:6379> acl getuser aliyundev #查询某个user的信息包括标志位,密码hash值,命令限制,key模糊匹配,订阅通道信息 1) "flags" 2) 1) "on" 2) "allchannels" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all" 7) "keys" 8) (empty list or set) 9) "channels" 10) 1) "*" 127.0.0.1:6379> acl genpass "b81947c220a8eed89b521b02213a9d075011a90a20332481bc661441b27a7fdb" 127.0.0.1:6379> acl genpass 10 #随机生成密码hash值 "8e0" 127.0.0.1:6379> acl genpass 12 "a3f" 127.0.0.1:6379> acl genpass 19 "d6fe1" 127.0.0.1:6379> acl genpass 9 "f43" 127.0.0.1:6379> acl setuser aliyundev off OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags"#标志位,表示一些状态是否开启有关 2) 1) "off" 2) "allchannels"#默认是订阅所有channels 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all" #默认是没有命令执行权限 7) "keys" 8) (empty list or set) #key的模糊匹配没限制。 9) "channels" 10) 1) "*"#和 allchannels 对应 127.0.0.1:6379> acl setuser aliyundev allkeys #同 acl setuser aliyundev allkeys ~* OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 2) "allkeys"#开启所有key的匹配 3) "allchannels" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all" 7) "keys" 8) 1) "*" #开启所有key的匹配模式值 9) "channels" 10) 1) "*" 127.0.0.1:6379> acl setuser aliyundev resetkeys #清空key匹配模式 OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 2) "allchannels" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all" 7) "keys" 8) (empty list or set)##清空后 9) "channels" 10) 1) "*" 127.0.0.1:6379> acl setuser aliyundev allchannels #语义同acl setuser aliyundev allchannels &* OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 2) "allchannels" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all" 7) "keys" 8) (empty list or set) 9) "channels" 10) 1) "*" 127.0.0.1:6379> acl setuser aliyundev resetchannels #清空channel模糊匹配 OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all" 7) "keys" 8) (empty list or set) 9) "channels" 10) (empty list or set) #清空后 127.0.0.1:6379> acl setuser aliyundev allcommands #可以执行所有命令 OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 2) "allcommands" #可以执行所有命令 3) "passwords" 4) (empty list or set) 5) "commands" 6) "+@all" 7) "keys" 8) (empty list or set) 9) "channels" 10) (empty list or set) 127.0.0.1:6379> acl setuser aliyundev nocommands #所有命令无法执行acl setuser aliyundev -@all OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 3) "passwords" #没命令。。 4) (empty list or set) 5) "commands" 6) "-@all" #没命令。。 7) "keys" 8) (empty list or set) 9) "channels" 10) (empty list or set) 127.0.0.1:6379> acl setuser aliyundev nopass #设置空密码,空密码无法登陆。 OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 2) "nopass" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all" 7) "keys" 8) (empty list or set) 9) "channels" 10) (empty list or set) 127.0.0.1:6379> acl setuser aliyundev resetpass #清空密码 OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all" 7) "keys" 8) (empty list or set) 9) "channels" 10) (empty list or set) 127.0.0.1:6379> acl setuser aliyundev >abc #设置密码为 abc OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 3) "passwords" 4) 1) "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" #密码的 sha256值 5) "commands" 6) "-@all" 7) "keys" 8) (empty list or set) 9) "channels" 10) (empty list or set) 127.0.0.1:6379> acl setuser aliyundev #abc #这里需写的事 sha256值就可以,可以通过 acl genpass来获取。仔细看报错可知 (error) ERR Error in ACL SETUSER modifier '#abc': The password hash must be exactly 64 characters and contain only lowercase hexadecimal characters 127.0.0.1:6379> acl setuser aliyundev #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad OK 127.0.0.1:6379> acl setuser aliyundev <abc #删除密码 abc OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 3) "passwords" 4) (empty list or set) #删除密码 abc后 5) "commands" 6) "-@all" 7) "keys" 8) (empty list or set) 9) "channels" 10) (empty list or set) 127.0.0.1:6379> acl setuser aliyundev !abc (error) ERR Error in ACL SETUSER modifier '!abc': The password hash must be exactly 64 characters and contain only lowercase hexadecimal characters 127.0.0.1:6379> acl setuser aliyundev <abcd (error) ERR Error in ACL SETUSER modifier '<abcd': The password you are trying to remove from the user does not exist 127.0.0.1:6379> acl setuser aliyundev >abcd OK 127.0.0.1:6379> acl setuser aliyundev !abcd #删除密码错误没有这个密码。。 (error) ERR Error in ACL SETUSER modifier '!abcd': The password hash must be exactly 64 characters and contain only lowercase hexadecimal characters 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 3) "passwords" 4) 1) "88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589" 5) "commands" 6) "-@all" 7) "keys" 8) (empty list or set) 9) "channels" 10) (empty list or set) 127.0.0.1:6379> acl setuser aliyundev !88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589 #删除 这个sha256的密码 OK 127.0.0.1:6379> acl setuser aliyundev ~abc* #key的模式匹配 OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all" 7) "keys" 8) 1) "abc*"#key的模式匹配 9) "channels" 10) (empty list or set) 127.0.0.1:6379> acl setuser aliyundev ~*abc* #key的模式匹配 OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all" 7) "keys" 8) 1) "abc*"#key的模式匹配 2) "*abc*"#key的模式匹配 9) "channels" 10) (empty list or set) 127.0.0.1:6379> acl setuser aliyundev &mychannels #订阅channels的模式匹配 OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all" 7) "keys" 8) 1) "abc*" 2) "*abc*" 9) "channels" 10) 1) "mychannels" #订阅channels的模式匹配 127.0.0.1:6379> acl setuser aliyundev &mychannels* #订阅channels的模式匹配 OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all" 7) "keys" 8) 1) "abc*" 2) "*abc*" 9) "channels" 10) 1) "mychannels" 2) "mychannels*" #订阅channels的模式匹配 127.0.0.1:6379> acl setuser aliyundev +get #增加命令 OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all +get" 7) "keys" 8) 1) "abc*" 2) "*abc*" 9) "channels" 10) 1) "mychannels" 2) "mychannels*" 127.0.0.1:6379> acl setuser aliyundev +get|nx #get 没有 nx子命令 OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all +get" 7) "keys" 8) 1) "abc*" 2) "*abc*" 9) "channels" 10) 1) "mychannels" 2) "mychannels*" 127.0.0.1:6379> acl setuser aliyundev +set|nx #set有nx子命令 OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all +get +set|nx" 7) "keys" 8) 1) "abc*" 2) "*abc*" 9) "channels" 10) 1) "mychannels" 2) "mychannels*" 127.0.0.1:6379> acl setuser aliyundev -get #删除get命令权限 OK 127.0.0.1:6379> acl setuser aliyundev -set #删除set命令权限 OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all" #删除命令权限后 7) "keys" 8) 1) "abc*" 2) "*abc*" 9) "channels" 10) 1) "mychannels" 2) "mychannels*" 127.0.0.1:6379> acl setuser aliyundev @string (error) ERR Error in ACL SETUSER modifier '@string': Syntax error 127.0.0.1:6379> acl setuser aliyundev +@string #所有string的命令均可以执行 OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all +@string" #所有string的命令均可以执行 7) "keys" 8) 1) "abc*" 2) "*abc*" 9) "channels" 10) 1) "mychannels" 2) "mychannels*" 127.0.0.1:6379> acl setuser aliyundev reset #恢复默认 OK 127.0.0.1:6379> acl getuser aliyundev 1) "flags" 2) 1) "off" 2) "allchannels" 3) "sanitize-payload" 3) "passwords" 4) (empty list or set) 5) "commands" 6) "-@all" 7) "keys" 8) (empty list or set) 9) "channels" 10) 1) "*" 127.0.0.1:6379>
真正的硬核来了:
阿里云已经上6.0 的高可用和 集群了,那么阿里云是如何使用 acl的呢。
我开了一个实例 发现文档里 说是不支持,但是呢,通过info commands,这个命令你就会看到这个命令的使用统计,还挺频繁,所以,阿里云的社区版6.0 内部是采用 acl认证的,但是内部已经开始 acl改造了,这也是针对未来的一种筹备和关注。
ACL的态度:
这个需求呢,个人觉得不是太重要,因为 redis还未真正成长为成为关键db的阶段,大部分人都还在当做一个缓存层,没有那种不丢失数据的强能力,或者需要等客户的使用习惯吧redis当做db之后 ACL功能才有意义。所以 这也是阿里不支持acl命令。