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

背景html

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

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

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

一、合法監聽接口

1.1 端口使用非默認端口

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

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

1.2 監聽地址不容許包括*

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

解決方案:由於若是有多網卡,應該將監聽地址設置爲只有數據庫客戶端須要鏈接的網卡地址。若是隻容許本機訪問,應該只監聽127.0.0.1。緩存

1.3 隱蔽的RedisCluster端口

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

解決方案:在端口矩陣中對額外的這個集羣端口有說明。修改源碼,新增一個redis.conf偏移量配置項cluster-port-increment,缺省配置+1,這樣能夠作到端口範圍可控,避免衝突。服務器

 

二、未公開接口

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.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須要有認證保護。

相關文章
相關標籤/搜索