背景
在Redis6.0以前的版本中,登录Redis Server只须要输入密码(前提配置了密码 requirepass )便可,不须要输入用户名,并且密码也是明文配置到配置文件中,安全性不高。而且应用链接也使用该密码,致使应用有全部权限处理数据,风险也极高。在Redis6.0有了ACL以后,终于解决了这些不安全的因素,能够按照不一样的需求设置相关的用户和权限。本文来介绍下Redis 6.0 ACL相关的配置和使用。具体的说明能够查看官方文档:ACL redis
说明
Redis ACL 是向后兼容的,即默认状况下用户为default,使用的是requirepass配置的密码。要是不使用ACL功能,对旧版客户端来讲彻底同样。Redis Auth能够有2种方式进行工做:安全
1:旧版本的使用方式,默认用户。兼容旧版本Redis的支持 AUTH <password> 2:新方式,还须要验证用户名 AUTH <username> <password>
由于须要验证用户名了,因此客户端的认证方式也多了参数:服务器
--user <username> 验证用户名 --pass <password> 验证密码,是参数-a的别名;配合--user使用 --askpass 强制用户输入带有STDIN掩码的密码
如今开始来讲明如何在Redis中根据ACL来定制须要的用户权限。首先看ACL的help,了解大体的使用方法:ACL help性能
> ACL help 1) ACL <subcommand> arg arg ... arg. Subcommands are: 2) LOAD -- 从ACL文件中从新载入用户信息. 3) SAVE -- 保存当前的用户配置信息到ACL文件. 4) LIST -- 以配置文件格式显示用户详细信息. 5) USERS -- 列出全部注册的用户名. 6) SETUSER <username> [attribs ...] -- 建立或则修改一个用户. 7) GETUSER <username> -- 获得一个用户的详细信息. 8) DELUSER <username> [...] -- 删除列表中的用户. 9) CAT -- 列出可用的类别. 10) CAT <category> -- 列出指定类别中的命令. 11) GENPASS [<bits>] -- 生成一个安全的用户密码. 12) WHOAMI -- 返回当前的链接用户. 13) LOG [<count> | RESET] -- 显示ACL日志条目.
具体使用方法:ui
在建立用户以前,先说明下ACL的规则,首先看下一个完整的用户权限的格式:加密
> ACL LIST --显示用户信息 1) "user default on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* +@all"
格式说明:spa
参 数 |
说明 |
user | 用户 |
default | 表示默认用户名,或则本身定义的用户名 |
on | 表示是否启用该用户,默认为off(禁用) |
#... | 表示用户密码,nopass表示不须要密码 |
~* | 表示能够访问的Key(正则匹配) |
+@ | 表示用户的权限,+/-表示受权仍是销权; @为权限类。+@all 表示全部权限 |
其中须要注意的有:rest
- 密码相关:
① 配置密码:一个用户能够设置不一样的密码,即一个用户能够有多个密码。
-- 添加密码 ## >开头: >password,明文密码; > ACL SETUSER zhoujy on >abc OK # 获取哈希值密码 echo -n "cba" | shasum -a 256 6d970874d0db767a7058798973f22cf6589601edab57996312f2ef7b56e5584d ## #开头: #hash,SHA-256哈希值 > ACL SETUSER zhoujy on #6d970874d0db767a7058798973f22cf6589601edab57996312f2ef7b56e5584d OK ## 查看 > ACL GETUSER zhoujy 1) "flags" 2) 1) "on" 3) "passwords" 4) 1) "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" 2) "6d970874d0db767a7058798973f22cf6589601edab57996312f2ef7b56e5584d" 5) "commands" 6) "-@all" 7) "keys" 8) (empty array) ## 认证密码 > AUTH zhoujy abc OK > AUTH zhoujy cba OK -- 移除密码 ## <开头: <password ,明文密码 > ACL SETUSER zhoujy <abc OK ## 用!开头: !hash,SHA-256哈希值 > ACL SETUSER zhoujy on !6d970874d0db767a7058798973f22cf6589601edab57996312f2ef7b56e5584d OK ## 查看 > ACL GETUSER zhoujy 1) "flags" 2) 1) "on" 3) "passwords" 4) (empty array) 5) "commands" 6) "-@all" 7) "keys" 8) (empty array) ## 认证密码 > AUTH zhoujy abc (error) WRONGPASS invalid username-password pair
② 清理/删除密码:经过nopass清理用户的密码,可是该用户链接仍是须要AUTH,只是密码能够是任意值
日志-- 清理/删除密码,能够用任意密码登录 ## 查看 > ACL GETUSER zhoujy 1) "flags" 2) 1) "on" 2) "allkeys" 3) "allcommands" 3) "passwords" 4) 1) "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" 2) "6d970874d0db767a7058798973f22cf6589601edab57996312f2ef7b56e5584d" 5) "commands" 6) "+@all" 7) "keys" 8) 1) "*" ## 删除、清理用户密码 > ACL SETUSER zhoujy nopass OK ## 查看 > ACL GETUSER zhoujy 1) "flags" 2) 1) "on" 2) "allkeys" 3) "allcommands" 4) "nopass" 3) "passwords" 4) (empty array) 5) "commands" 6) "+@all" 7) "keys" 8) 1) "*" ## 验证 > AUTH zhoujy --须要AUTH (error) WRONGPASS invalid username-password pair > AUTH zhoujy '' --能够输入任何密码 OK -- 清理/删除密码,不能登录,须要设置密码后才能登录 ## 查看 > ACL GETUSER zhoujy 1) "flags" 2) 1) "on" 2) "allkeys" 3) "allcommands" 3) "passwords" 4) 1) "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" 2) "6d970874d0db767a7058798973f22cf6589601edab57996312f2ef7b56e5584d" 5) "commands" 6) "+@all" 7) "keys" 8) 1) "*" ## 删除、清理用户密码 > ACL SETUSER zhoujy resetpass OK > ACL GETUSER zhoujy 1) "flags" 2) 1) "on" 2) "allkeys" 3) "allcommands" 3) "passwords" 4) (empty array) 5) "commands" 6) "+@all" 7) "keys" 8) 1) "*" ## 验证,被resetpass重置密码以后,不能登录,只能设置密码或则设置nopass才能登录 > AUTH zhoujy (error) WRONGPASS invalid username-password pair > AUTH zhoujy '' (error) WRONGPASS invalid username-password pair
③ 重置用户和密码:其实是执行 resetpass,resetkeys,off,-@all
code## 查看 > ACL LIST 1) "user default on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* +@all" 2) "user zhoujy on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* +@all" ## 重置用户 > ACL SETUSER zhoujy reset OK ## 查看 > ACL LIST 1) "user default on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* +@all" 2) "user zhoujy off -@all"
④ 获取随机密码:
-- 生成随机密码 > ACL GENPASS "7a3288b05577cb6fea9b1a9a8bcfe10d9589e64be74e8a0e16c131ba896c7bde"
- 键模式:~<pattern>,通配符模式。好比: ~*表示容许访问全部key,也能够用
allkeys来表示~*。resetkeys 表示清空它以前全部的键模式,以后的键模式不影响。
-- 能够操做foo开头和bar:开头的全部key > ACL SETUSER zhoujy on >abc ~foo* ~bar:*+@all OK ## 查看 > ACL LIST 1) "user default on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* +@all" 2) "user zhoujy on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~foo* ~bar:*+@all" -- 只能操做ob:开头的key,前面的key模式被resetkeys清空了 > ACL SETUSER zhoujy on >abc ~foo* ~bar:* resetkeys ~ob:*+@all OK ## 查看 > ACL LIST 1) "user default on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* +@all" 2) "user zhoujy on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~ob:*+@all" -- 操做全部key,allkeys 和 ~* 同样 > ACL SETUSER zhoujy allkeys +@all OK > ACL LIST 1) "user default on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* +@all" ## 查看 2) "user zhoujy on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~*+@all"
- 权限相关:权限这块涉及到的比较多:权限的类别、类别里包含的命令,以及子权限。
注意:-@all表示没有任何权限;+@all表示有全部权限;
-- 返回权限的类别 > 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" -- 返回指定类别中的命令,下面hash是上面返回的一个结果 > ACL CAT hash 1) "hsetnx" 2) "hset" 3) "hlen" 4) "hmget" 5) "hincrbyfloat" 6) "hgetall" 7) "hvals" 8) "hscan" 9) "hkeys" 10) "hstrlen" 11) "hget" 12) "hdel" 13) "hexists" 14) "hincrby" 15) "hmset"
从上面的权限列表里看到:权限对key的类型和命令的类型进行了分类,若有对类型进行分类:string、hash、list、set、sortedset,和对命令类型进行分类:connection、admin、dangerous。 以及对每一个分类的方法进行说明,如上面查看hash类型key的一些方法。
受权方法:+<command>:将命令添加到用户能够调用的命令列表中,如+@hash -<command>: 将命令从用户能够调用的命令列表中移除 +@<category>: 添加一类命令,如:@admin, @set, @hash ... 能够ACL CAT 查看具体的操做指令。特殊类别@all表示全部命令,包括当前在服务器中存在的命令,以及未来将经过模块加载的命令 -@<category>: 相似+@<category>,从客户端能够调用的命令列表中删除命令 +<command>|subcommand: 容许不然禁用特定子命令。注意,这种形式不容许像-DEBUG | SEGFAULT那样,而只能以“ +”开头 allcommands:+@all的别名,容许全部命令操做执行。注意,这意味着能够执行未来经过模块系统加载的全部命令。 nocommands:-@all的别名,不容许全部命令操做执行。
① 添加指定类型的权限:+@hash
-- 添加hash类型key的全部权限 > ACL SETUSER zhoujy +@hash OK ## 查看 > ACL LIST 1) "user default on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* +@all" 2) "user zhoujy on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* -@all +@hash"
说明:用户zhoujy只有对hash类型的key有权限。
② 删除指定类型的权限:-@hash
-- 删除hash类型key的全部权限 > ACL SETUSER zhoujy -@hash +@string OK ## 查看 > ACL LIST 1) "user default on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* +@all" 2) "user zhoujy on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad -@all +@string"
说明:用户zhoujy移除对hash类型的key有权限。
③ 指定特定key的权限:如sortedset:~z*,z开头的key-- 访问指定key的正则 > ACL SETUSER zhoujy ~z* +@sortedset -@string OK ## 查看 > ACL LIST 1) "user default on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* +@all" 2) "user zhoujy on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~z* -@all +@sortedset"
说明:用户zhoujy只有对z开头的key有权限。
④ 受权只读/只写的权限:+@read、+@write
-- 受权全部key的只读权限 > ACL SETUSER zhoujy ~* +@read OK ##查看 > ACL LIST 1) "user default on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* +@all" 2) "user zhoujy on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* -@all +@read +@hash +@bitmap +@geo -georadiusbymember -hsetnx -setbit -hset -geoadd -bitop -hincrbyfloat -hdel -bitfield -hincrby -hmset -georadius" -- 受权全部key的只写权限 > ACL SETUSER zhoujy +@write OK ##查看 192.168.163.134:8379> ACL LIST 1) "user default on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* +@all" 2) "user zhoujy on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* -@all +@write +@list +@string +@stream +@fast +@blocking -dbsize -getrange -scard -xrevrange -zrank -llen -xread -ttl -get -ping -watch -publish -hlen -xrange -stralgo -zcount -getbit -lastsave -readonly -hmget -hello -zcard -discard -hstrlen -xinfo -hget -exists -bitfield_ro -select -role -zlexcount -zrevrank -lolwut -hexists -touch -lindex -unwatch -sismember -strlen -xlen -asking -type -mget -time -xpending -echo -multi -auth -readwrite -lrange -pttl -zscore -substr"
说明:用户zhoujy对全部key有只读或则只写的权限,若是下个这对指定key,则替换 ~* 便可。
⑤ 受权管理权限:@admin-- 受权管理权限 > ACL SETUSER zhoujy on >abc ~* +@admin OK ## 查看 > ACL LIST 1) "user default on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* +@all" 2) "user zhoujy on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* -@all +@admin +@dangerous -flushall -flushdb -swapdb -keys -role -sort -migrate -restore-asking -restore -info"
说明:用户zhoujy有管理权限,包含了危险操做的类型,但排除了-开头命令的权限。
⑥ 容许特定类型key的子命令权限:
-- 设置子命令。 > ACL SETUSER zhoujy on >abc ~* -client +client|getname +client|setname OK ##查看 > ACL LIST 1) "user default on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* +@all" 2) "user zhoujy on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* -@all +client|getname +client|setname"
说明:开始删除CLIENT命令,而后添加了两个容许的子命令。请注意,不能相反,即不能+在前面,只能添加而不是排除子命令,由于未来可能会添加新的子命令。注意子命令匹配可能会增长一些性能损失。
⑦:特定用途的帐号权限:Sentinel 和 Replicas-- Sentinel:容许用户在主和副本实例中都有如下命令权限 > ACL SETUSER sentinel-user >somepassword +client +subscribe +publish +ping +info +multi +slaveof +config +client +exec on OK -- Replicas:副本须要在主实例上有如下命令权限 > ACL SETUSER replica-user >somepassword +psync +replconf +ping on OK
- 保存、加载相关:save、load
经过ACL建立的用户是保存在内存里的,若是Redis Server重启则ACL建立的用户会丢失,因此在建立完用户后须要用save保存,在重启以后须要用load加载。有两种方式进行保存和加载:
1,使用ACL命令:ACL SAVE、ACL LOAD 2,使用Redis配置,用户被定义,而后重启服务器并生效。 或者使用外部ACL文件,使用ACL LOAD 来导入ACL信息
注意:ACL的配合文件须要事先手动touch,不然实例启动会失败。在redis.conf里配置和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.
在redis.conf中指定用户是一种很是简单的方法,适用于简单的用例。 当有多个用户要定义时,在复杂的环境中,强烈建议使用ACL文件。该2个文件里的配置内容是一致的,能够相互进行配置,如格式以下:在redis.conf和users.acl里的格式
-- 配置文件 user default on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* +@all user zhoujy on #ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ~* +@all
① 保存ACL规则
-- 保存ACL规则 > ACL SAVE OK
② 加载ACL规则
-- 加载ACL规则 > ACL LOAD OK
说明:在使用ACL配置文件以后,若是设置了默认用户(default)规则的话,须要看配置文件中aclfile和requirepass参数的前后顺序,密码以最后出现的为准。
- 日志相关:显示最近的ACL安全事件列表
经过ACL LOG [<count> | RESET] 返回ACL的日志信息,能够指定条目显示,也能够进行重置:
-- 显示日志信息 > ACL LOG 1 1) 1) "count" 2) (integer) 1 3) "reason" 4) "auth" 5) "context" 6) "toplevel" 7) "object" 8) "AUTH" 9) "username" 10) "zhoujy" 11) "age-seconds" 12) "282.90499999999997" 13) "client-info" 14) "id=5 addr=192.168.163.134:35246 fd=7 name= age=403 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=36 qbuf-free=32732 obl=0 oll=0 omem=0 events=r cmd=auth user=zhoujy" -- 重置日志,相似slow > acl log reset OK
到此,大体的权限介绍已经结束,后续会不定时更新相关内容。
场景说明
- 建立DBA管理帐号
> ACL SETUSER dba on #6d0ac515af9df81653ed0aa3ffa692663c3f556079791e2f00a4578990da66f3 allkeys +@all OK
- 建立读写帐号
> ACL SETUSER readwrite on >abc allkeys -@all +@read +@write OK
- 建立只读帐号
> ACL SETUSER readonly on >abc allkeys -@all +@read OK
- 建立只写帐号
> ACL SETUSER write_user on >abc allkeys -@all +@write OK
- 建立复制帐号
> ACL SETUSER replica-user >abc -@all +psync +replconf +ping on OK
- 建立哨兵帐号
> ACL SETUSER sentinel-user >abc -@all +client +subscribe +publish +ping +info +multi +slaveof +config +client +exec on OK
- 建立监控帐号
> ACL SETUSER monitor on >abc +monitor OK
- 建立指定key、有指定类型权限的帐号
-- 指定对h开头的hash类型的key有权限 > ACL SETUSER ops_user on >abc ~h* +@hash OK
其中key的模式是正则匹配,须要~开头,针对权限则是hash的类,其权限能够经过ACL CAT hash查看。
注意:以上操做完只有须要执行ACL SAVE。否则重置以后用户信息所有都清空了。
总结
在默认配置中,Redis 6(第一个具备ACL的版本)的工做方式与Redis的旧版本彻底相同,即每一个新链接都可以调用每一个可能的命令并访问每一个键,所以ACL功能与旧版本向后兼容。一样使用requirepass配置指令配置密码的旧方法仍然能够按预期工做(只是为默认用户设置密码)。关于ACL更多的操做指南能够看官方文档。PS:若是后续有补充会继续更新到文章中。