Redis系列(十一)、Redis6新特性之ACL安全策略(用戶權限管理)

目錄

介紹

配置文件模式

conf文件模式

外部ACLFILE模式 

對比conf和aclfile模式

命令行模式

介紹 

ACL規則

啓用和禁用用戶

允許和禁止調用命令

允許或禁止訪問某些Key

爲用戶配置有效密碼

ACL HELP

ACL LIST

ACL USERS

ACL WHOAMI

ACL CAT

ACL SETUSER

ACL GETUSER

ACL DELUSER

ACL SAVE

ACL LOAD

ACL GENPASS

ACL LOG

AUTH

小結


好消息!好消息!Redis出權限管理功能了!你還不來看看嗎?

自從Redis6.0以來,大家呼籲了很久的權限管理功能(ACL[access control list 訪問控制列表])終於發佈了,通過此功能,我們可以設置不同的用戶並對他們授權命令或數據權限。這樣我們可以避免有些用戶的誤操作導致數據丟失或避免數據泄露的安全風險。


Redis系列文章:

Redis系列(一)、CentOS7下安裝Redis6.0.3穩定版

Redis系列(二)、數據類型之字符串String 

Redis系列(三)、數據類型之哈希Hash

Redis系列(四)、數據類型之列表List

Redis系列(五)、數據類型之無序集合Set

Redis系列(六)、數據類型之有序集合ZSet(sorted_set)

Redis系列(七)、常用key命令

Redis系列(八)、常用服務器命令 

Redis系列(九)、Redis的“事務”及Lua腳本操作

Redis系列(十)、詳解Redis持久化方式AOF、RDB以及混合持久化


介紹

在Redis6之前的版本,我們只能使用requirepass參數給default用戶配置登錄密碼,同一個redis集羣的所有開發都共享default用戶,難免會出現誤操作把別人的key刪掉或者數據泄露的情況,那之前我們也可以使用rename command的方式給一些危險函數重命名或禁用,但是這樣也防止不了自己的key被其他人訪問。

因此Redis6版本推出了ACL(Access Control List)訪問控制權限的功能,基於此功能,我們可以設置多個用戶,並且給每個用戶單獨設置命令權限和數據權限。 爲了保證向下兼容,Redis6保留了default用戶和使用requirepass的方式給default用戶設置密碼,默認情況下default用戶擁有Redis最大權限,我們使用redis-cli連接時如果沒有指定用戶名,用戶也是默認default。鼓掌!

我們可以在配置文件中或者命令行中設置ACL,如果使用配置config文件的話需要重啓服務,使用配置aclfile文件或者命令行授權的話無需重啓Redis服務但需要及時將權限持久化到磁盤,否則下次重啓的時候無法恢復該權限。 

官網:https://redis.io/topics/acl

配置文件模式

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

conf文件模式

使用redis.conf文件配置default和其他用戶的ACL權限

1.在config文件中配置default用戶的密碼
requirepass 123456

2.在config文件中添加DSL命令配置用戶ACL權限
【使用方式在下文】

3.在config文件中註釋aclfile的路徑配置(默認是註釋的)
#aclfile /opt/app/redis6/users.acl

4.重啓redis服務
systemctl restart redis

因此我們可以直接在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.

外部ACLFILE模式 

 使用外部aclfile文件配置Default和其他用戶的ACL權限

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

2.在config文件中註釋default用戶的密碼,因爲開啓aclfile之後,requirepass的密碼就失效了:
redis.conf
#requirepass 123456

users.acl
user default on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~* +@all

3.在config文件中配置aclfile的路徑,然後創建該文件,否則重啓redis服務會報錯找不到該文件
aclfile /opt/app/redis6/users.acl
touch /opt/app/redis6/users.acl

4.在外部aclfile文件中添加DSL命令配置用戶ACL權限
【使用方式在下文】

5.重啓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來登陸:  

 

對比conf和aclfile模式

 在redis.conf和aclfile模式中配置DSL 官方更推薦使用aclfile,因爲如果在redis,conf中配置了權限之後需要重啓redis服務才能將配置的權限加載至redis服務中來,但如果使用aclfile模式,可以調用acl load命令將aclfile中配置的ACL權限熱加載進環境中,類似於Mysql中的flush privileges。

對比conf和aclfile
  redis.conf users.acl
配置方式 DSL DSL
加載ACL配置 重啓Redis服務 ACL LOAD命令
持久化ACL配置 CONFIG REWRITE命令 ACL SAVE命令

命令行模式

介紹 

上面可以看到,我們在配置文件中配置的ACL權限,需要執行ACL LOAD或者重啓Redis服務才能生效,事實上我們可以直接在命令行下配置ACL,在命令行模式下配置的權限無需重啓服務即可生效。我們也可以在命令行模式下配置ACL並將其持久化到aclfile或者config文件中(這取決於配置文件中選擇的是config模式還是外部aclfile模式),一旦將權限持久化到aclfile或cofig文件中,下次重啓就會自動加載該權限,如果忘記持久化,一旦服務宕機或重啓,該權限就會丟失。

如果使用config模式,將ACL權限持久化到redis.conf文件中使用下面的命令:
config rewrite

如果使用aclfile模式,將ACL權限持久化到users.acl文件中使用下面的命令:
acl save

ACL規則

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

啓用和禁用用戶

  • on:啓用用戶:可以以該用戶身份進行認證。
  • off:禁用用戶:不再可以使用此用戶進行身份驗證,但是已經通過身份驗證的連接仍然可以使用。

允許和禁止調用命令

  • +<command>:將命令添加到用戶可以調用的命令列表中。
  • -<command>:將命令從用戶可以調用的命令列表中移除。
  • +@<category>:允許用戶調用 <category> 類別中的所有命令,有效類別爲@admin,@set,@sortedset等,可通過調用ACL CAT命令查看完整列表。特殊類別@all表示所有命令,包括當前和未來版本中存在的所有命令。
  • -@<category>:禁止用戶調用<category> 類別中的所有命令。
  • +<command>|subcommand:允許使用已禁用命令的特定子命令。
  • allcommands:+@all的別名。包括當前存在的命令以及將來通過模塊加載的所有命令。
  • nocommands:-@all的別名,禁止調用所有命令。

允許或禁止訪問某些Key

  •  ~<pattern>:添加可以在命令中提及的鍵模式。例如~** allkeys 允許所有鍵。
  • resetkeys:使用當前模式覆蓋所有允許的模式。如: ~foo:* ~bar:*  resetkeys ~objects:* ,客戶端只能訪問匹配 object:* 模式的 KEY。

爲用戶配置有效密碼

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

 

ACL HELP

使用下面的命令查看help文檔:

acl help

 

ACL LIST

我們可以使用ACL LIST命令來查看當前活動的ACL,默認情況下,有一個“default”用戶:

127.0.0.1:6379> acl list
1) "user default on nopass ~* +@all"

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

ACL USERS

返回所有用戶名:

acl users

ACL WHOAMI

返回當前用戶名:

acl whoami

 

ACL CAT

查看命令類別,用於授權:

ACL CAT:顯示所有的命令類別 。
ACL CAT <category>:顯示所有指定類別下的所有命令。 

ACL SETUSER

使用下面的命令創建或修改用戶屬性,username區分大小寫

#username區分大小寫
#若用戶不存在則按默認規則創建用戶,若存在則修改用戶屬性
SETUSER <username> [attribs ...]

#若用戶不存在,則按默認規則創建用戶。若用戶存在則該命令不做任何操作。
ACL SETUSER <username> 

#若用戶不存在,則按默認規則創建用戶,併爲其增加<rules>。若用戶存在則在已有規則上增加 <rules>。
ACL SETUSER <username> <rules> 

默認規則下新增的用戶處於非活躍狀態,且沒有密碼,同時也沒有任何命令和key的權限: 

 

例:使用下面的命令新增用戶/修改用戶的權限:

#on爲活躍狀態,密碼爲wyk123456,允許對所有csdn開頭的key使用get和set命令
ACL SETUSER wyk on >wyk123456 ~csdn* +get +set

#爲wyk用戶新增一個可用密碼csdn8888
ACL SETUSER wyk on >csdn8888

#爲wyk用戶新增list類別下所有命令的權限
ACL SETUSER wyk on +@list

 

 

ACL GETUSER

使用下面的命令查看用戶的ACL權限:

#查看用戶的ACL權限
acl getuser <username>

ACL DELUSER

刪除指定的用戶:

#刪除指定的用戶
acl deluser <username>

ACL SAVE

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

#將acl權限持久化到磁盤的aclfile中
acl save

#如果使用redis.conf配置ACL,則使用config rewrite命令將ACL持久化到redis.conf中
config rewrite

 

ACL LOAD

我們也可以直接在aclfile中修改或新增ACL權限,修改之後不會立刻生效,我們可以在redis命令行中執行acl load將該aclfile中的權限加載至redis服務中:

#將aclfile中的權限加載至redis服務中
acl load

ACL GENPASS

隨機返回sha256密碼,我們可以直接使用該密文配置ACL密碼:

#隨機返回一個256bit的32字節的僞隨機字符串,並將其轉換爲64字節的字母+數字組合字符串
acl genpass

#可指定位數
acl genpass 32
acl genpass 64

 

ACL LOG

查看ACL安全日誌:

acl log

AUTH

使用auth命令切換用戶:

AUTH <username> <password>

小結

由於Redis是高性能的數據庫,正常情況下每秒可以接收百萬級別的請求,因此我們的用戶密碼一定要是非常複雜的組合,否則很容易就會被暴利跑字典給破解了,不管怎麼說,這次Redis6版本帶來的新特性ACL權限控制也是解決了我們很大的痛點,終於可以權限隔離了!

希望本文對你有幫助,請點個贊鼓勵一下作者吧~ 謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章