1. 程式人生 > 其它 >第三章 ACL安全策略

第三章 ACL安全策略

一、ACL概述

在Redis6之前的版本,我們只能使用requirepass引數給default使用者配置登入密碼,同一個redis叢集的所有開發都共享default使用者,難免會出現誤操作把別人的key刪掉或者資料洩露的情況。

因此Redis6版本推出了ACL(Access Controller List)訪問控制權限的功能,基於此功能,我們可以設定多個使用者,並且給每個使用者單獨設定命令許可權和資料許可權。為了保證向下相容,Redis6保留了default使用者和使用requirepass的方式給default使用者設定密碼,預設情況下default使用者擁有Redis最大許可權,我們使用redis-cli連線時如果沒有指定使用者名稱,使用者也是預設default。

二、配置ACL

配置ACL的方式有兩種,一種是在config檔案中直接配置,另一種是在外部aclfile中配置。配置的命令是一樣的,但是兩種方式只能選擇其中一種,我們之前使用requirepass給default使用者設定密碼 預設就是使用config的方式,執行config rewrite重寫配置後會自動在config檔案最下面新增一行記錄配置default的密碼和許可權。

1. Redis設定密碼

在Redis 6.0之前,Redis只有一個default使用者也是Redis中的超級管理員使用者,如果要將其設定密碼,需要修改Redis配置檔案,具體修改如下:
requirepass 123456
# 修改之後,再次進入Redis時,發現已經沒有許可權操作了。

[root@alvin-test-os redis]# redis-cli --raw
127.0.0.1:6379> set a b
NOAUTH Authentication required.

# 這個時候我們需要使用密碼的方式進入
[root@alvin-test-os redis]# redis-cli -a 123456 --raw
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> set a b
OK

三、使用ACL

我們可以直接在config配置檔案中使用上面default使用者ACL這行DSL命令設定使用者許可權,或者我們也可以配置外部aclfile配置許可權。配置aclfile需要先將config中配置的DSL註釋或刪除,因為Redis不允許兩種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.

1.使用外部ACLFILE模式

使用外部aclfile檔案配置Default和其他使用者的ACL許可權。

1.註釋redis.conf中所有已授權的ACL命令,如:
#user default on 
#8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~* +@all

2.在config檔案中註釋default使用者的密碼,因為開啟aclfile之後,requirepass的密碼就失效了:
redis.conf
#requirepass 123456

3.在config檔案中配置aclfile的路徑,然後建立該檔案,否則重啟redis服務會報錯找不到該檔案
aclfile /usr/local/redis/etc/users.acl
touch /usr/local/redis/etc/users.acl

4.重啟redis服務或使用aclfile load命令載入許可權
systemctl restart redis
或
在redis命令列中執行:
aclfile load
開啟aclfile之後不再推薦在redis.conf檔案中通過requirepass配置default的密碼,因為它不再生效,同時開啟aclfile之後也不能使用redis-cli -a xxx登陸,必須使用redis-cli --user xxx --pass yyy來登陸。在沒設定密碼的時候也可以無密碼登入

# 這個時候顯示的是無密碼狀態
127.0.0.1:6379> acl list
1) "user default on nopass ~* +@all"

在redis.conf和aclfile模式中配置DSL 官方更推薦使用aclfile,因為如果在redis,conf中配置了許可權之後需要重啟redis服務才能將配置的許可權載入至redis服務中來,但如果使用aclfile模式,可以呼叫acl load命令將aclfile中配置的ACL許可權熱載入進環境中,類似於Mysql中的flush privileges。但同時我們也可以使用命令:config rewrite 將acl許可權初始化到redis.conf中;同時執行acl save可以將acl配置持久化到aclfile中。

2. ACL規則

ACL是使用DSL(Domain specific language)定義的,該DSL描述了使用者能夠執行的操作。該規則始終從上到下,從左到右應用,因為規則的順序對於理解使用者的實際許可權很重要。ACL規則可以在redis.conf檔案以及users.acl檔案中配置DSL,也可以在命令列中通過ACL命令配置。

3. 啟用和禁用

1.on:啟用使用者:可以以該使用者身份進行認證。
2.off:禁用使用者:不再可以使用此使用者進行身份驗證,但是已經通過身份驗證的連線仍然可以使用。

4. 案例

# 建立一個使用者, 預設情況下是非活躍狀態
127.0.0.1:6379> ACL SETUSER xiaozhang
OK

# 檢視使用者
127.0.0.1:6379> acl list
user alvin off #6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090 -@all
user default on nopass ~* +@all
user xiaozhang off -@all
 
# 將使用者設定成活躍狀態
127.0.0.1:6379> ACL SETUSER xiaozhang on
OK

# 再次檢視使用者列表,發現小張已經變成了活躍狀態
127.0.0.1:6379> acl list
user alvin off #6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090 -@all
user default on nopass ~* +@all
user xiaozhang on -@all

5. 允許和禁止呼叫命令

命令 解釋
+ 將命令新增到使用者可以呼叫的命令列表中。
- 將命令從使用者可以呼叫的命令列表中移除。
+@ 允許使用者呼叫 類別中的所有命令,有效類別為@admin,@set,@sortedset等,可通過呼叫ACL CAT命令檢視完整列表。特殊類別@all表示所有命令,包括當前和未來版本中存在的所有命令。
-@ 禁止使用者呼叫 類別中的所有命令。
+|subcommand 允許使用已禁用命令的特定子命令。
allcommands +@all的別名。包括當前存在的命令以及將來通過模組載入的所有命令。
nocommands -@all的別名,禁止呼叫所有命令。

6. 案例

# 將xiaozhang使用者增加密碼、設定訪問以name開頭的key的許可權和set許可權
127.0.0.1:6379> ACL SETUSER xiaozhang on >abc123 ~name* +set
OK

# 我們可以看到xiaozhang目前只具有set許可權
127.0.0.1:6379> acl list
user xiaozhang on #6ca13d52ca70c883e0...392593af6a84118090 ~name* -@all +set

# 切換使用者
127.0.0.1:6379> AUTH xiaozhang abc123
OK

# 設定鍵值對
127.0.0.1:6379> set name xiaozhang
OK

# 沒有獲取許可權
127.0.0.1:6379> get name
NOPERM this user has no permissions to run the 'get' command or its subcommand

7. 允許和禁止訪問某些key

命令 解釋
~ 新增可以在命令中提及的鍵模式。例如~ allkeys 允許所有鍵。
* resetkeys 使用當前模式覆蓋所有允許的模式。如: ~foo:* ~bar:* resetkeys ~objects:* ,客戶端只能訪問匹配 object:* 模式的 KEY。
# 將xiaozhang使用者增加密碼、設定訪問以name開頭的key的許可權和set許可權
127.0.0.1:6379> ACL SETUSER xiaozhang on >abc123 ~name* +set
OK

8. 密碼配置

命令 解釋
> 將此密碼新增到使用者的有效密碼列表中。例如,>mypass將“mypass”新增到有效密碼列表中。該命令會清除使用者的nopass標記。每個使用者可以有任意數量的有效密碼。
< 從有效密碼列表中刪除此密碼。若該使用者的有效密碼列表中沒有此密碼則會返回錯誤資訊。
# 將此SHA-256雜湊值新增到使用者的有效密碼列表中。該雜湊值將與為ACL使用者輸入的密碼的雜湊值進行比較。允許使用者將雜湊儲存在users.acl檔案中,而不是儲存明文密碼。僅接受SHA-256雜湊值,因為密碼雜湊必須為64個字元且小寫的十六進位制字元。
! 從有效密碼列表中刪除該雜湊值。當不知道雜湊值對應的明文是什麼時很有用。
nopass 移除該使用者已設定的所有密碼,並將該使用者標記為nopass無密碼狀態:任何密碼都可以登入。resetpass命令可以清除nopass這種狀態。
resetpass 情況該使用者的所有密碼列表。而且移除nopass狀態。resetpass之後使用者沒有關聯的密碼同時也無法使用無密碼登入,因此resetpass之後必須新增密碼或改為nopass狀態才能正常登入。
reset 重置使用者狀態為初始狀態。執行以下操作resetpass,resetkeys,off,-@all。

9. 案例

# 檢視使用者列表
127.0.0.1:6379> acl list
user alvin off -@all
user default on nopass ~* +@all
 
# 將alvin使用者設定密碼
127.0.0.1:6379> ACL SETUSER alvin on >abc123
OK
127.0.0.1:6379> acl list
user alvin on #6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090 -@all
user default on nopass ~* +@all

# 切換使用者
127.0.0.1:6379> auth alvin abc123
OK

# alvin沒有set許可權
127.0.0.1:6379> set aaa bbb
NOPERM this user has no permissions to run the 'set' command or its subcommand

四、 ACL常用操作

1. ACL LIST

我們可以使用ACL LIST命令來檢視當前活動的ACL,預設情況下,有一個“default”使用者。
127.0.0.1:6379> ACL list
1) "user default on nopass ~* +@all"
127.0.0.1:6379>

其中user為關鍵詞,default為使用者名稱,後面的內容為ACL規則描述,on表示活躍的,nopass表示無密碼, ~* 表示所有key,+@all表示所有命令。所以上面的命令表示活躍使用者default無密碼且可以訪問所有命令以及所有資料。

2. ACL USER

返回所有使用者名稱。
127.0.0.1:6379> acl users
1) "default"
127.0.0.1:6379>

3. ACL WHOAMI

返回當前使用者名稱。
127.0.0.1:6379> ACL WHOAMI
"default"

4. 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"

5. ACL SETUSER

若使用者不存在,則按預設規則建立使用者。若使用者存在則該命令不做任何操作。
127.0.0.1:6379> ACL SETUSER alvin
OK
127.0.0.1:6379> acl list
1) "user alvin off -@all"
2) "user default on nopass ~* +@all"

6. ACL GETUSER

使用下面的命令檢視使用者的ACL許可權。
127.0.0.1:6379> ACL GETUSER xiaozhang
flags
on
passwords
6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090
commands
-@all +set
keys
name*
127.0.0.1:6379>

7.

ACL DELUSER

刪除指定的使用者。
#刪除指定的使用者
acl deluser <username>

127.0.0.1:6379> ACL DELUSER alvin
1

8.ACL SAVE

我們可以使用acl save命令將當前伺服器中的ACL許可權持久化到aclfile中,如果沒持久化就關閉redis服務,那些ACL許可權就會丟失,因此我們每次授權之後一定要記得ACL SAVE將ACL許可權持久化到aclfile中。

# 檢視users.acl
[root@alvin-test-os redis]# cat etc/users.acl
 
# 檢視acl使用者
[root@alvin-test-os redis]# redis-cli --raw
127.0.0.1:6379> acl list
user default on nopass ~* +@all
user xiaozhang on #6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090 ~name* -@all +set

# 儲存acl許可權配置
127.0.0.1:6379> acl save
OK
127.0.0.1:6379> exit
 
# 檢視acl配置檔案已經被寫入
[root@alvin-test-os redis]# cat etc/users.acl
user default on nopass ~* +@all
user xiaozhang on #6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090 ~name* -@all +set

9. ACL LOAD

我們也可以直接在aclfile中修改或新增ACL許可權,修改之後不會立刻生效,我們可以在redis命令列中執行acl load將該aclfile中的許可權載入至redis服務中。
#將aclfile中的許可權載入至redis服務中
acl load
 
# 檢視acl使用者列表
127.0.0.1:6379> acl list
user default on nopass ~* +@all
user xiaozhang on #6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090 ~name* -@all +set

# 過載
127.0.0.1:6379> ACL LOAD
OK 

# 檢視新使用者已經加入
127.0.0.1:6379> acl list
user alvin on #6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090 ~name* -@all +set
user default on nopass ~* +@all
user xiaozhang on #6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090 ~name* -@all +set

10. AUTH

使用auth命令切換使用者。
AUTH <username> <password>