Redis緩存數據庫安全加固指導(一)


背景

在眾多開源緩存技術中,Redis無疑是目前功能最為強大,應用最多的緩存技術之一,參考2018年國外數據庫技術權威網站DB-Engines關於key-value數據庫流行度排名,Redis暫列第一位,但是原生Redis版本在安全方面非常薄弱,很多地方不滿足安全要求,如果暴露在公網上,極易受到惡意攻擊,導致數據泄露和丟失。

本文主要是在原生開源軟件Redis3.0基礎上,系統的在安全特性方面進行的增強,很多增強點涉及了開源代碼的修改,后續章節闡述的Redis緩存數據庫的安全規范, 理論上適用於所有應用Redis的產品。

本系列共連載三篇,分九個章節,本文從合法監聽接口,未公開接口,訪問通道控制三個章節闡述了Redis緩存數據庫加固措施

1、合法監聽接口

1.1 端口使用非默認端口

安全問題:Redis Server監聽的端口默認為6379,容易被掃描攻擊。

解決方案:修改為非默認端口,並在端口矩陣中說明。

1.2 監聽地址不允許包括*

安全問題:Redis支持監聽0.0.0.0。

解決方案:因為如果有多網卡,應該將監聽地址設置為只有數據庫客戶端需要連接的網卡地址。如果只允許本機訪問,應該只監聽127.0.0.1。

1.3 隱蔽的RedisCluster端口

安全問題:官方RedisCluster方案缺省會增加一個集群端口,且是在客戶端端口偏移10000,這個問題非常隱蔽。

解決方案:在端口矩陣中對額外的這個集群端口有說明。修改源碼,新增一個redis.conf偏移量配置項cluster-port-increment,缺省配置+1,這樣可以做到端口范圍可控,避免沖突。

 

2、未公開接口

2.1 賬號管理(重要)

安全問題:Redis只有一個超戶,權限過大。

解決方案:權限最小化原則,增加配置項,角色區分超戶,普通用戶和只讀用戶三種。

角色

redis.conf對應配置項

權限說明

超戶

requirepass

所有功能。

普通用戶

requireuserpass

不能進行管理類命令,如shutdown等

只讀用戶

requirereaduserpass

在普通用戶基礎上,進一步限制只能進行讀操作。沒有script命令權限。

普通用戶不能進行的操作有:

命令

解釋

save

SAVE 命令執行一個同步保存操作,將當前Redis 實例的所有數據快照(snapshot) 以RDB 文件的形式保存到硬盤。

bgsave

在后台異步(Asynchronously) 保存當前數據庫的數據到磁盤。

bgrewriteaof

執行一個AOF 文件重寫操作。重寫會創建一個當前AOF 文件的體積優化版本。即使BGREWRITEAOF 執行失敗,也不會有任何數據丟失,因為舊的AOF 文件在BGREWRITEAOF 成功之前不會被修改。

shutdown

停止所有客戶端 如果有至少一個保存點在等待,執行SAVE 命令 如果AOF 選項被打開,更新AOF 文件 關閉redis 服務器(server)

sync

用於復制功能(replication) 的內部命令。

psync

用於復制功能(replication) 的內部命令。

replconf

暫無用處

monitor

實時打印出Redis 服務器接收到的命令,調試用。

slaveof

SLAVEOF 命令用於在Redis 運行時動態地修改復制(replication) 功能的行為。

debug

調試命令

config

配置參數

restore

反序列化給定的序列化值,並將它和給定的key 關聯。

migrate

將key 原子性地從當前實例傳送到目標實例的指定數據庫上,一旦傳送成功,key 保證會出現在目標實例上,而當前實例上的key 會被刪除。

dump

序列化給定key ,並返回被序列化的值,使用RESTORE 命令可以將這個值反序列化為Redis 鍵

2.2 Redis-cli隱藏密碼

安全問題:通過在redis-cli指定-a參數,密碼會被ps出來,屬於敏感信息。

解決方案:修改Redis源碼,在main進入后,立即隱藏掉密碼,避免被ps出來。(可參考開源Mysql代碼)

2.3 Redis-cli工具使用說明

     對於需在現網維護階段使用的命令/參數、端口等接入方式(包括但不限於產品的生產、調測、維護用途),需通過產品資料等向客戶或監管機構公開或受限公開。

2.4 禁止在腳本中通過sudo方式切換用戶執行redis-cli

安全問題: redis-cli訪問參數帶密碼敏感信息,會被ps出來,也容易被系統記錄操作日志。

解決方案:改為通過API方式(Python可以使用redis-py)來安全訪問,禁止通過sudo方式切換到dbuser賬號使用redis-cli。

重現條件:可以通過iptables禁掉redis端口來模擬重現。

 

3、訪問通道控制

3.1 預共享秘鑰認證(重要)

安全問題:Redis原生認證存在重放攻擊:只是簡單的交互一次auth xxx

解決方案:采用預共享秘鑰(對稱加密算法+隨機數的雙向認證),同時在方案設計上做到最大限度兼容,讓客戶端改造成本最小,目前平台配套目前支持客戶端有:Java,Python,C,Lua。

方案設計如下:

Redis認證協議變更,其中auth命令區分兩種功能,通過首字母區分:

auth命令含義

區分

認證第一階段:客戶端傳遞隨機數

請求:auth <RAND_C

響應:-ERR >TokenBA

認證第二階段

auth >TokenAB

預共享秘鑰認證時序圖

說明:Redis為文本協議, 安全隨機數長度固定為32字節的可顯示字符串,連接2個隨機數的分隔符為”@”。

主要認證流程:

1.客戶端向服務端執行命令: auth <RAND_C 

1)      首字母<表示是認證第一階段。(便於服務端從協議層區分)

2)      RAND_C表示客戶端生成安全隨機數。

2.服務端產生響應錯誤回復

1)      獲取RAND_C,並生成RAND_S

2)      產生TokenBA=AES128(RAND_S@RAND_C)

3)      響應錯誤回復:-ERR >TokenBA

說明:錯誤描述為服務端生成的安全隨機數。

3.客戶端驗證

1)      驗證TokenBA是否合法

解密出RAND_S@RAND_C,看看RAND_C是否是自己生成的隨機數

2)      客戶端產生TokenAB=AES128(RAND_C@RAND_S@dbname@ossdbuser@pwd)

3)      調用認證接口: auth >TokenAB

4.服務端認證

1)      驗證TokenAB是否合法

解密出RAND_C@RAND_S,看看RAND_S是否是自己生成的隨機數

2)      驗證用戶和密碼合法性: dbname@ossdbuser@pwd

3.2 認證時加上庫名

安全問題:Redis沒有庫名,系統如果只通過用戶名+密碼,容易猜測和攻擊。

解決方案:通過認證時帶上庫名, 因為每個服務的庫名都配置不同,增加攻擊復雜度, 認證格式以dbname@dbuser@pwd區分。

3.3 端口矩陣

安全問題:Redis也是一種數據庫服務,一般一個進程占用一個端口,集群還會額外多占用一個端口。

解決方案:在端口矩陣寫明系統申請的Redis端口范圍。

3.4 客戶端認證超時時間

安全問題:原生Redis沒有限制客戶端認證超時時間,存在慢攻擊。

解決方案:修改源碼,限制在60秒內認證成功,否則服務器將主動斷開連接。

說明: 控制完成客戶端認證的時間上限。這可以防止無效客戶端長時間占用連接通道。

3.5 支持SSL通信

安全問題:增加SSL通信可以提高數據傳輸的安全。

解決方案:

1.不改動官方源碼,通過在客戶端和服務端部署SSL Proxy,類似stunnel。

2.支持SSL可配置,涉及開源代碼修改。

說明:因為Redis屬於交互密集型,每秒處理幾萬次請求,支持SSL后性能會有比較大損失。

3.6 支持ACL控制

安全問題:目前Redis沒有ACL控制。

解決方案:

1.  目前基於平台共享秘鑰,其中秘鑰是隨機生成,每套系統不一樣,間接也做到了IP范圍控制。

2.  通過iptables控制進一步限制接入IP范圍。

3.  如果要具體控制到用戶+IP級別,類似Mysql認證。作者antirez已經意識到這個問題,有望在未來版本提供,鏈接如下:Multi users AUTH and ACLs for Redis

3.7 Jedis客戶端相關

安全問題:官方推薦Java客戶端Jedis集群最新版還不支持認證。

解決方案:增加認證參數,與服務端共享秘鑰認證保持一致。

安全問題:Jedis認證接口密碼為參數string。

解決方案:Jedis客戶端認證新增一套char[]接口。

3.8 集群認證相關

1. RedisCluster多主多從,內部高度自制,因此Redis的認證masterauth需要加密保存到配置文件。

2.配置集群關系時,基於Gossip協議,Cluster meet需要有認證保護。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM