Redis 6.0 訪問控制列表ACL說明

背景

      在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

到此,大體的權限介紹已經結束,後續會不定時更新相關內容。

場景說明

  1. 建立DBA管理帳號
    > ACL SETUSER dba on #6d0ac515af9df81653ed0aa3ffa692663c3f556079791e2f00a4578990da66f3 allkeys +@all OK
  2. 建立讀寫帳號
    > ACL SETUSER readwrite on >abc allkeys -@all +@read +@write OK
  3. 建立只讀帳號
    > ACL SETUSER readonly on >abc allkeys -@all +@read OK
  4. 建立只寫帳號
    > ACL SETUSER write_user on >abc allkeys -@all +@write OK
  5. 建立複製帳號
    > ACL SETUSER replica-user >abc -@all +psync +replconf +ping on OK
  6. 建立哨兵帳號
    > ACL SETUSER sentinel-user >abc -@all +client +subscribe +publish +ping +info +multi +slaveof +config +client +exec on OK
  7. 建立監控帳號
    > ACL SETUSER monitor on >abc +monitor OK
  8. 建立指定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:若是後續有補充會繼續更新到文章中。

參考文檔:

https://redis.io/topics/acl

https://redis.io/commands/acl-setuser

相關文章
相關標籤/搜索