众所周知 redis 6.0 两个比较大的特性 一个是多线程IO 一个是ACL。
今天主要讲解下 ACL特性,以及我的一些看法。结尾有对阿里云redis的一些调研彩蛋。哈哈
什么是ACL:
官方定义:ACL 是 Access Control List 缩写,主要是限制特定连接的 特定数据访问权限和特定命令执行。采用不同的user 采用不同的 acl策略来实现,默认值兼容 之前的 auth passwd模式的。
TheRedisAUTHcommandwasextendedinRedis6, sonowitispossibletouseitinthetwo-argumentsform: AUTH<username><password>Whenitisusedaccordingtotheoldform, thatis: AUTH<password>
127.0.0.1:6379>aclhelp1) ACL<subcommand> [<arg> [value] [opt] ...]. Subcommandsare: 2) CAT [<category>] 3) Listallcommandsthatbelongto<category>, orallcommandcategories4) whennocategoryisspecified. 5) DELUSER<username> [<username> ...] 6) Deletealistofusers. 7) GETUSER<username>8) Gettheuser's details.9) GENPASS [<bits>] 10) Generateasecure256-bituserpassword. Theoptional`bits`argumentcan11) beusedtospecifyadifferentsize. 12) LIST13) Showusersdetailsinconfigfileformat. 14) LOAD15) ReloadusersfromtheACLfile. 16) LOG [<count>|RESET] 17) ShowtheACLlogentries. 18) SAVE19) SavethecurrentconfigtotheACLfile. 20) SETUSER<username><attribute> [<attribute> ...] 21) Createormodifyauserwiththespecifiedattributes. 22) USERS23) Listalltheregisteredusernames. 24) WHOAMI25) Returnthecurrentconnectionusername. 26) HELP27) Printsthishelp. 127.0.0.1:6379>
ACL 命令目录
可以看到 通过 acl cat 可以看到不同中类型的
127.0.0.1:6379>aclcat1) "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>aclsetuseraliyundevonOK127.0.0.1:6379>aclgetuseraliyundev1) "flags"2) 1) "on"2) "allchannels"3) "passwords"4) (emptylistorset) 5) "commands"6) "-@all"7) "keys"8) (emptylistorset) 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命令。