摘要:在傳統架構的 Redis 中,客戶端是可以使用全部命令的,但是訪問 Redis 實例時是沒有能力控制運行着 Redis 的系統的。這是個特殊的例子,但是,正常情況下,對 Redis 的非法訪問需要通過實現 ACLs,驗證用戶輸入和決定 Redis 實例上可以執行哪些操作這些方式來控制。

Redis常規安全模式

Redis 被設計成僅有可信環境下的可信用戶纔可以訪問。這意味着將 Redis 實例直接暴露在網絡上或者讓不可信用戶可以直接訪問 Redi s的 tcp 端口或 Unix 套接字,是不安全的。

正常情況下,使用Redis的web應用程序是將Redis作爲數據庫,緩存,消息系統,網站的前端用戶將會查詢Redis來生成頁面,或者執行所請求的操作,或者被web應用程序用戶所觸發。這種情況下,web應用程序需要對不可信的用戶(訪問web應用程序的用戶瀏覽器)訪問Redis進行處理。這是個特殊的例子,但是,正常情況下,對 Redis 的非法訪問需要通過實現 ACLs,驗證用戶輸入和決定 Redis 實例上可以執行哪些操作這些方式來控制。

總而言之,Redis 並沒有最大地去優化安全方面,而是盡最大可能去優化高性能和易用性。

網絡安全

僅有可信的網絡用戶纔可以訪問 Redis 的端口,因此運行 Redis 的服務器應該只能被用 Redis 實現的應用程序的計算機直接訪問。

一般情況下一臺直接暴露在 Internet 的計算機,例如一個虛擬化 Linux 實例(Linode, EC2,…),防火牆應該防止外部用戶訪問它的redis端口。用戶仍可以通過本地接口來訪問 Redis。

記住在 redis.conf 文件中增加下面這一行配置就可以把 Redis 綁定在單個接口上。

bind 127.0.0.1

不禁止外部訪問 Redis 的話,將會產生非常嚴重的後果。比如,一個 FLUSHALL 操作就可以當做外部攻擊來刪除 Redis 上的所有數據。

認證的特性

雖然 Redis 沒有嘗試去實現訪問控制,但是提供了一個輕量級的認證方式,可以編輯 redis.conf 文件來啓用。當認證授權方式啓用後,Redis 將會拒絕來自沒有認證的用戶的任何查詢。一個客戶端可以通過發送 AUTH 命令並帶上密碼來給自己授權。

這個密碼由系統管理員在 redis.conf 文件裏面用明文設置,它需要足夠長以應對暴力攻擊,這樣子設置有以下兩個原因:

redis.conf

但同時密碼控制也會影響到從庫複製,從庫必須在配置文件裏使用 masterauth 指令配置相應的密碼纔可以進行復制操作。

masterauth yoursecurepasswordhereplease

認證層的目標是提供多一層的保護。假如防火牆或者其它任何系統防護攻擊失敗的話,外部客戶端如果沒有認證密碼的話將依然無法訪問 Redis 實例。AUTH 命令就像其它Redis命令一樣,是通過非加密方式發送的,因此無法防止擁有足夠的訪問網絡權限的攻擊者進行竊聽。

數據加密支持

Redis並不支持加密。爲了實現在網絡上或者其它非可信網絡訪問 Redis 實例,需要實現新增的保護層,例如 SSL 代理。

官方推薦的SSL 代理: spiped

禁用的特殊命令

在 Redis 中可以禁用命令或者將它們重命名成難以推測的名稱,這樣子普通用戶就只能使用部分命令了。例如,一個虛擬化的服務器提供商可能提供管理Redis實例的服務。在這種情況下,普通用戶可能不被允許調用 CONFIG 命令去修改實例的配置,但是能夠提供刪除實例的系統需要支持修改配置。

在這種情況下,你可以從命令表中重命名命令或者禁用命令。這個特性可以在 redis.conf 文件中進行配置。例如:

rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52

在上面這個例子中,CONFIG 命令被重命名成一個不好猜測的名稱。把命令重命名成一個空字符串可以禁用掉該命令,例如下面這個例子:

rename-command CONFIG ""

外部客戶端通過仔細構造的輸入觸發的攻擊

即便沒有外部訪問權限,也有種攻擊可以讓攻擊者從外部觸發。例如一些攻擊者有能力向 Redis 中插入數據,觸發 Redis 內部數據結構中最差的算法複雜度,例如一個攻擊者可以通過提交表單提交大量一樣的字符串到哈希表裏,使得 O(1) 的算法複雜度(平均時間)達到最差的O(N) ,Redis 將需要更多的CPU來處理,到最後會導致無法提供服務爲了防範這類特殊的攻擊,Redis 的哈希函數使用 per-excution 的僞隨機種子。

Redis 用 qsort 算法來實現 SORT 命令。當前這個算法還不算隨機的,所以通過有意構造輸入可能引發最糟糕情況的算法複雜度。

字符串轉義和NoSQL注入

Redis 的協議沒有字符串轉移的概念,因此一般情況下普通客戶端無法實現注入的。該協議採用二進制安全的前綴長度字符串。通過 EVAL 和 EVALSHA 命令運行 Lua 腳本也是安全的。雖然這是個很奇怪的用法,應用程序應避免使用不明來源的字符串來寫Lua 腳本。

代碼安全

在傳統架構的 Redis 中,客戶端是可以使用全部命令的,但是訪問 Redis 實例時是沒有能力控制運行着 Redis 的系統的。本質上,Redis 使用一直的最好的編程方法來寫安全的代碼,防止出現緩存溢出,格式錯誤和其他內存損壞問題。但是,使用 CONFIG 命令修改服務器配置的能力使得用戶可以改變程序的工作目錄和備份文件的名字。這讓用戶可以將 RDB 文件寫在任意路徑,這個安全問題容易引起不受信任的代碼在 Redis 上運行。

Redis 不需要 root 權限來運行,建議使用僅能運行 Redis 的用戶運行。Redis 的作者正在調查給 Redis 增加一個新參數來防止 CONFIG SET/GET dir 和其它命令運行時配置指令的可能。這可以防止客戶端強制要求服務器在任意位置寫文件。

參考自:[Redis 文檔中心](http://www.redis.cn/topics/security.html)

自己補充了少部分內容,學習 Redis 十分推薦 Redis 文檔中心,從入門到精通都有

相關文章