1. 程式人生 > >Redis 6.0 新特性 ACL 介紹

Redis 6.0 新特性 ACL 介紹

# Redis 6.0 新特性 ACL 介紹 ## Intro 在 Redis 6.0 中引入了 ACL(Access Control List) 的支援,在此前的版本中 Redis 中是沒有使用者的概念的,其實沒有辦法很好的控制權限,redis 6.0 開始支援使用者,可以給每個使用者分配不同的許可權來控制權限。 下面我們就來介紹一下 Redis 6.0 中的 ACL 吧,下面的示例可以通過 docker 運行了一個 redis-6.0 的容器來實驗的 ## 執行一個 redis 6.0 的 docker 容器 因為我本地已經裝了一個 redis,6379 埠已經被禁用了,所以使用了 16379 埠 ``` bash docker run -d --name=redis-server-6.0 -p 16379:6379 redis:6.0-alpine ``` 建立成功之後就可以使用 redis-cli 連上去了 ![](https://img2020.cnblogs.com/blog/489462/202007/489462-20200703165137142-416040252.png) 我是直接用的本地的 redis-cli,如果本地沒有也可以使用 docker 容器內部的 redis-cli, ``` bash docker exec -it redis-server-6.0 redis-cli ``` ![](https://img2020.cnblogs.com/blog/489462/202007/489462-20200703165510722-1114918800.png) ## AUTH 在 redis 的之前版本中是有一個 “AUTH” 命令,但是之前的版本只是支援一個 Password,是沒有使用者的概念的,這就導致所有的客戶端相當於是使用同一個賬戶來操作 redis 的,redis 6.0 擴充套件了 AUTH 的語法: ``` AUTH ``` 同時也相容了舊版本的 `AUTH` ``` AUTH ``` 使用這種方式時,也就是隻提供密碼,相當於使用了一個預設的使用者 “default”,通過這樣的方式,實現了對低版本的相容 ## ACL ### ACL 使用場景 在使用 ACL 之前,您可能會問自己,這個功能主要用來幹嘛,它能幫我實現什麼,ACL 可以幫助你實現下面兩個主要目標: - 通過限制對命令和金鑰的訪問來提高安全性,以使不受信任的客戶端無法訪問,而受信任的客戶端僅具有對資料庫的最低訪問級別才能執行所需的工作。例如,某些客戶端可能僅能夠執行只讀命令, - 提高操作安全性,以防止由於軟體錯誤或人為錯誤而導致程序或人員訪問 Redis,從而損壞資料或配置。例如,沒有必要讓工作人員從 Redis 呼叫 `FLUSHALL` 命令。 ACL 的另一種典型用法與託管Redis例項有關。Redis通常由管理內部Redis基礎結構的內部公司團隊為其所擁有的其他內部客戶提供的一項託管服務,或者由雲提供商在軟體即服務設定中提供。 在這兩種設定中,我們都希望確保為客戶排除配置命令。過去,通過命令重新命名來完成此操作的方法是一種技巧,它使我們可以長時間不用 ACL 生存,但使用體驗並不理想。 ### 通過 ACL 命令來配置 ACL 規則 ACL是使用 DSL(domain specific language)定義的,該 DSL 描述了給定使用者能夠執行的操作。此類規則始終從左到右從第一個到最後一個實施,因為有時規則的順序對於理解使用者的實際能力很重要。 預設情況下,有一個使用者定義,稱為default。 我們可以使用 `ACL LIST` 命令來檢查當前啟用的 ACL 規則 ``` bash 127.0.0.1:6379> ACL LIST 1) "user default on nopass ~* +@all" ``` 引數說明: 參 數 | 說明 ------|------ user | 使用者 default |  表示預設使用者名稱,或則自己定義的使用者名稱 on | 表示是否啟用該使用者,預設為off(禁用) #... | 表示使用者密碼,nopass表示不需要密碼 ~* | 表示可以訪問的Key(正則匹配) +@ | 表示使用者的許可權,“+”表示授權許可權,有許可權操作或訪問,“-”表示還是沒有許可權; @為許可權分類,可以通過 `ACL CAT` 查詢支援的分類。+@all 表示所有許可權,nocommands 表示不給與任何命令的操作許可權 許可權對key的型別和命令的型別進行了分類,如有對資料型別進行分類:string、hash、list、set、sortedset,和對命令型別進行分類:connection、admin、dangerous。 執行 `ACL CAT` 可以檢視支援的許可權分類列表 ``` bash 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 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" ``` ## 配置使用者許可權 我們可以通過兩種主要方式建立和修改使用者: - 使用 ACL 命令及其 ACL SETUSER 子命令。 - 修改伺服器配置(可以在其中定義使用者)並重新啟動伺服器,或者如果我們使用的是外部 `ACL` 檔案,則只需發出 `ACL LOAD` 即可。 ``` bash +:將命令新增到使用者可以呼叫的命令列表中,如+@hash -: 將命令從使用者可以呼叫的命令列表中移除 +@: 新增一類命令,如:@admin, @set, @hash ... 可以`ACL CAT` 檢視具體的操作指令。特殊類別@all表示所有命令,包括當前在伺服器中存在的命令,以及將來將通過模組載入的命令 -@: 類似+@,從客戶端可以呼叫的命令列表中刪除命令 +|subcommand: 允許否則禁用特定子命令。注意,這種形式不允許像-DEBUG | SEGFAULT那樣,而只能以“ +”開頭 allcommands:+@all的別名,允許所有命令操作執行。注意,這意味著可以執行將來通過模組系統載入的所有命令。 nocommands:-@all的別名,不允許所有命令操作執行。 ``` ### 使用 `ACL SETUSER` 命令 首先,讓我們嘗試最簡單的 `ACL SETUSER` 命令呼叫: ``` bash > ACL SETUSER alice OK ``` 在上面的示例中,我根本沒有指定任何規則。如果使用者不存在,這將使用just created的預設屬性來建立使用者。如果使用者已經存在,則上面的命令將不執行任何操作。 讓我們檢查一下預設的使用者狀態: ``` bash > ACL LIST 1) "user alice off -@all" 2) "user default on nopass ~* +@all" ``` 剛建立的使用者“ alice”為: 處於關閉狀態,即已禁用。 `AUTH` 將不起作用。 無法訪問任何命令。請注意,預設情況下,該使用者是預設建立的,無法訪問任何命令,因此-@all可以忽略上面輸出中的,但是 `ACL LIST` 嘗試是顯式的,而不是隱式的。 最後,沒有使用者可以訪問的金鑰模式。 使用者也沒有設定密碼。 這樣的使用者是完全無用的。讓我們嘗試定義使用者,使其處於活動狀態,具有密碼,並且僅可以使用GET命令訪問以字串“ cached:”開頭的鍵名稱。 ``` bash > ACL SETUSER alice on >p1pp0 ~cached:* +get OK ``` 現在,使用者可以執行某些操作,但是會拒絕執行其他沒有許可權的操作: ``` bash > AUTH alice p1pp0 OK > GET foo (error) NOPERM this user has no permissions to access one of the keys used as arguments > GET cached:1234 (nil) > SET cached:1234 zap (error) NOPERM this user has no permissions to run the 'set' command or its subcommand ``` 事情按預期進行。為了檢查使用者alice的配置(請記住使用者名稱區分大小寫),可以使用 `ACL LIST`的替代方法 `ACL GETUSER` ``` bash > ACL GETUSER alice 1) "flags" 2) 1) "on" 3) "passwords" 4) 1) "2d9c75..." 5) "commands" 6) "-@all +get" 7) "keys" 8) 1) "cached:*" ``` 如果我們使用RESP3,則輸出的可讀性可能更高,因此將其作為地圖回覆返回: ``` bash > ACL GETUSER alice 1# "flags" => 1~ "on" 2# "passwords" => 1) "2d9c75..." 3# "commands" => "-@all +get" 4# "keys" => 1) "cached:*" ``` > 多次呼叫ACL SETUSER會發生什麼 瞭解多次呼叫 `ACL SETUSER` 會發生什麼非常重要。重要的是要知道,每個`SETUSER`呼叫都不會重置使用者,而只會將ACL規則應用於現有使用者。 僅在之前不知道的情況下才重置使用者: 在這種情況下,將使用歸零的ACL建立一個全新的使用者,即該使用者無法執行任何操作,被禁用,沒有密碼等等:為了安全起見,最佳預設值。 但是,以後的呼叫只會逐步修改使用者,因此例如以下呼叫順序將導致 `myuser` 能夠同時呼叫 `GET` 和 `SET`: ``` bash > ACL SETUSER myuser +set OK > ACL SETUSER myuser +get OK > ACL LIST 1) "user default on nopass ~* +@all" 2) "user myuser off -@all +set +get" ``` ### 使用外部 `ACL` 檔案 有兩種方法可以將使用者儲存在Redis配置中,一種是 `redis.conf` 中配置,一種是使用一個獨立的外部 acl 檔案,這兩種方式不相容,只能選擇一種方式 通常外部檔案的方式更靈活,推薦使用。 內部redis.conf和外部ACL檔案中使用的格式是完全相同的,因此從一個切換到另一個很簡單 配置內容如下: ``` user ... acl rules ... ``` 來看一個示例: ``` user worker +@list +@connection ~jobs:* on >ffa9203c493aa99 ``` 當您要使用外部ACL檔案時,需要指定名為的配置指令 `aclfile`,如下所示: ``` bash aclfile /etc/redis/users.acl ``` 當僅在redis.conf 檔案內部直接指定幾個使用者時,可以使用CONFIG REWRITE以便通過重寫將新的使用者配置儲存在檔案中。 但是,外部ACL檔案功能更強大。您可以執行以下操作: * 使用 `ACL LOAD` 重新載入外部 ACL 檔案,通常在你手動修改了這個檔案,希望 redis 重新載入的時候使用,需要注意的是要確保 acl 檔案內容的正確性 * 使用 `ACL SAVE` 將當前 ACL 配置儲存到一個外部檔案 ## More redis 6.0 的 ACL 特性為我們帶來了更好的許可權控制方案,安全性更好,有需要的快來體驗一下吧 ## Reference -
- -