在2019年紐約的Redis Day上,Salvatore Sanfilippo(AKA Antirez)介紹了即將發布的Redis 6.0的新特性。以下是關於ACLs的內容。
ACLs簡介
在過去的十年中,Redis都會有這樣的問題:
用戶執行FLUSHALL
,OK現在整個數據庫就空了,或者執行DEBUG SEGFAULT
,然后Redis的進程就crash退出了。
(右側運行redis-server,左側執行debug segfault后server崩潰退出)
在以前解決這個問題的辦法可能是在Redis配置中將危險命令進行rename:
rename-command FLUSHALL ""
這樣將命令更名為隨機字符串或者直接屏蔽掉,以滿足需要。
缺少危險命令管理就會導致很多問題,比如當你使用網絡上的一些庫的時候,你壓根就不知道別人會不會在里面加些FLUSHALL
這樣的命令,或者你也可以每次用外部代碼都進行一輪Code Review。
ACLs,也就是Access Control List,當有了ACLs之后,你就可以控制比如:
當前的用戶(連接)只允許使用RPOP
,LPUSH
這些命令,其他命令都無法調用。
是不是很方便?來看看ACLs是怎么工作的。
最佳實踐
首先你要做的是定義用戶。
當登錄的時候,舊版本中默認用戶(defaule user)是可以做任何事的,在Redis 6.0中你可以定義默認用戶:
127.0.0.1:6379> ACL setuser antirez on >password1 >password2 >foobar +@all ~*
setuser
...on
表示啟用此用戶,off則是只定義一個不可用(unaccessable)的用戶。
>password1 >password2 >foobar
表示設置了3個密碼,可以用來做密碼輪換策略。
+@all
表示用戶可以使用所有權限,+
后面跟命令權限如+get
,或者+@
后面跟某一類權限。
~*
表示可用(accessable)的鍵名,這里是*
也就是所有鍵都可被訪問。
127.0.0.1:6379> ACL WHOAMI
"default"
現在是處於默認用戶下的,切換用戶:
127.0.0.1:6379> AUTH antirez foobar
OK
在以前AUTH后面是直接跟密碼的,現在是用戶名和密碼。
127.0.0.1:6379> ACL WHOAMI
"antirez"
因為之前給這個用戶設置的是所有命令可用+所有鍵可見,所以現在跟default用戶沒有什么區別:
127.0.0.1:6379> GET foo
(nil)
127.0.0.1:6379> SET foo bar
OK
現在去掉一些權限:
127.0.0.1:6379> ACL setuser antirez -SET
把這個用戶的SET
權限去掉后,就不能進行這個操作了:
127.0.0.1:6379> GET foo
"bar"
127.0.0.1:6379> SET foo 123
(error) NOPERM this user has no permissions to run the 'set' command or its subcommand
再來查看一下現在的ACL list:
127.0.0.1:6379> ACL list
1) "user antirez on >password1 >password2 >foobar ~* +@all -set"
2) "user default on nopass ~* +@all"
類似的,你也可以限制用戶可以用任何命令但是卻只能看部分鍵,如object*
。
備注
ACLs的實現使用了一些小技巧,像用上了命令的位圖(commands' bitmaps),以便讓它不會在速度上有所下降。
不使用ACLs的話就和原來的Redis 5一樣,使用ACLs當然會有一些額外的開銷,但是它們非常小,你在benchmarks中不會察覺到新舊版本的區別。