12.3、安全的Redis

安全的Redis

2015年11月,全球數萬個Redis節點遭受到了攻擊,所有數據都會被清除了,只有一個叫crackit的鍵存在,這個鍵的值很像一個公鑰。

數據丟失對于很多Redis的開發者來說是致命的,經過相關機構的調查發現,被攻擊的Redis有以下特點:

  • Redis所在的機器有外網IP

  • Redis以默認端口6379為啟動端口,并且是對外網開放的。

  • Redis是以root用戶啟動的

  • Redis沒有設置密碼

  • Redis的bind設置為0.0.0.0或者""

攻擊者充分利用Redis的dir和dbfilename兩個配置可以利用config set動態設置,以及RDB持久化的特性,將自己的公鑰寫入到目標機器的/root/.ssh/authotriezed_keys文件中,從而實現了對目標機器的攻陷。

假設機器A是攻擊者的機器(內網IP:10.10.xx.192),機器B是被攻擊者機器(外網IP:123.16.xx.182),上面部署著一個滿足上述五個特性的Redis,下面我們來模擬整個攻擊過程:

1)首先確認當前(攻擊前)機器A不能通過SSH訪問機器B,因為沒有權限。

2)由于機器B的外網對外開通了Redis的6379端口,所以可以直接連接到Redis上執行flushall操作,注意此事破壞性已經很大了。

3)在機器A生成公鑰,并將公鑰保存到一個文件my.pub中。

4)將鍵crackit的值設置為公鑰。

5)將Redis的dir設置為/root/.ssh目錄,dbfilename設置為authorized_keys,執行save命令生成RDB文件。此時機器B的/roor/.ssh/authorized_keys包含了攻擊者的公鑰,之后攻擊者就可以“為所欲為”了。

6)此時機器A再通過SSH協議訪問機器B,發現可以順利登錄,登錄后可以觀察/root/.ssh/authorized_keys,可以發現它就是RDB文件。

誰也不想自己的Redis以及機器就這樣被攻擊吧?本節我們來介紹如何讓Redis足夠安全。

Redis的設計目標是一個在內網運行的輕量級高性能鍵值服務,因為是在內網運行,所以對于安全方面沒有做太多的工作,Redis值提供了簡單的密碼機制,并且沒有做用戶權限的相關劃分。那么,在日常對于Redis的開發和運維中要注意哪些方面才能讓Redis服務不僅能提供高效穩定的服務,還能保證在一個足夠安全的網絡環境下運行呢?下面將從7個方面進行介紹。

  1. Redis密碼機制

    1. 簡單的密碼機制

      Redis提供了requirepass配置為Redis提供密碼功能,如果添加這個配置,客戶端就不能通過redis-cli -h {ip} -p {port}來執行命令。例如下面啟動一個密碼為hello_redis-devops的redis:

      redis-server --requirepass hello_redis_devpos

      此時通過redis-cli執行命令會受到沒有權限的提示:

      # redis-cli
      127.0.0.1:6379> ping
      (error) NOAUTH Authentication required.
      

      Redis提供了兩種方式訪問配置了密碼的Redis:

      • redis-cli -a參數。使用redis-cli連接Redis時,添加-a加密碼的參數,如果密碼正確就可以正常訪問Redis了,具體操作如下:
      # redis-cli -h 127.0.0.1 -p 6379 -a hello_redis_devops
      127.0.0.1:6379> ping
      PONG
      
      • auth命令。通過redis-cli連接后,執行auth加密碼命令,如果密碼正確就可以正常訪問訪問Redis了,具體操作如下:
      # redis-cli
      127.0.0.1:6379> auth hello_redis-devops
      OK
      127.0.0.1:6379> ping
      PONG
      
    2. 運維建議

      這種密碼機制能在一定程度上保護Redis的安全,但是在使用requirepass時候要注意以下幾點:

      • 密碼要足夠復雜(64個字節以上),因為Redis的性能很高,如果密碼比較單間,完全是可以在一段時間內通過暴力破解來破譯密碼。

      • 如果是主從結構的Redis,不要忘記在從節點的配置中加入masterauth(master的密碼)配置,否則會造成主從節點同步失效。

      • auth是通過明文進行傳輸的,所以也不是100%可靠,如果被攻擊者劫持也相當危險。

  2. 偽裝危險命令

    1. 引入rename-command

      Redis中包含了很多“危險”命令,一旦錯誤使用或者誤操作,后果不堪設想,例如如下命令:

      • keys:如果鍵值較多,存在阻塞Redis的可能性。

      • flushall/flushdb:數據全部被清除。

      • save:如果鍵值較多,存在阻塞Redis的可能性。

      • debug:例如debug reload會重啟Redis。

      • config:config應該交給管理員使用。

      • shutdown:停止Redis。

      理論上這些命令不應該給普通開發人員使用,那有沒有什么好的方法能夠防止這些危險命令被隨意執行呢?Redis提供了rename-conmmand配置解決這個問題。下面直接用一個例子說明rename-command的作用。例如當前Redis包含了10000個鍵值對,現使用flushall將全部是數據清除:

      127.0.0.1:6379> flushall
      OK
      ``
      
      例如Redis添加如下配置:
      
      `rename-command flushall flushalltest`
      
      那么執行flushall命令的話,會收到Redis不認識flushall的錯誤提示,說明我們成功地使用rename-command對flushall命令做了偽裝:
      
      

      127.0.0.1:6379> flushall
      (error) ERR unknonwn command 'flushall'

      
      而如果執行flushalltest,那么就可以實現flushall的功能了,這就是rename-command的作用,管理員可以對認為比較危險的命令做rename-command處理。
      
      
    2. 沒有免費的午餐

      rename-command雖然對Redis的安全有一定幫助,但是天下并沒有免費的午餐。使用了rename-command時可能會帶來如下麻煩:

      • 管理員要對自己的客戶端進行修改,例如jedis.flushall()操作內部使用的是flushalll命令,如果用rename-command后需要修改為新的命令,有一定的開發和維護成本。

      • rename-command配置不支持config set,所以啟動前一定要確定哪些命令需要使用rename-command。

      • 如果AOF和RDB文件包含了rename-command之前的命令,Redis將無法啟動,因為此時它識別不了rename-command之前的命令。

      • Redis源碼中有一些命令是寫死的,rename-command可能造成Redis無法正常工作。例如Sentinel節點在修改配置時直接使用了config命令,如果對config使用rename-command,會造成Redis Sentinel無法正常工作。

    3. 最佳實踐

      在使用rename-command的相關配置時,需要注意以下幾點:

      • 對于一些危險的命令(例如flushall),不管是內網還是外網,一律使用rename-command配置。

      • 建議第一次配置Redis時,就應該配置rename-command,因為rename-command不支持config set。

      • 如果涉及主從關系,一定要保持主從節點配置一致性,否則存在主從數據不一致的可能性。

  3. 防火墻

    可以使用防火墻限制輸入和輸出的IP或者IP范圍、端口或者端口范圍,在比較成熟的公司都會對有waiwangIP的服務器做一些端口的限制,例如只允許80端口對外開放。因為一般來說,開放外網IP的服務器中Web服務器比較多,但通常存儲服務器的端口無序對外開放,防火墻是一個限制外網訪問Redis的必殺技。

  4. bind

    1. 對于bing的錯誤認識

      很多開發者在一開始看到bind這個配置是都是這么認為的:指定Redis只接收來自于某個網段IP的客戶端請求。

      但事實上bing指定的是Redis和哪個網卡進行綁定,和客戶端是什么網段沒有關系。ifconfig命令獲取網卡信息包含了三個IP地址:

      • 內網地址:10.10.xx.192

      • 外網地址:220.181.xx.123

      • 回環地址:127.0.0.1

      如果當前Redis配置了bind 10.10.xx.192,那么Redis訪問只能通過10.10.xx.192這塊網卡進入,通過redis-cli -h 220.181.xx.123 -p 6379和本機redis-cli -h 128.0.0.1 -p 6379都無法連接到Redis。只能通過10.10.xx.192作為redis-cli的參數。

      bind參數可以設置多個,例如下面配置表示當前Redis只接收來自10.10.xx.192和127.0.0.1的網絡流量:

      bind 10.10.xx.192 127.0.0.1
      

      運維提示:Redis3.0中bind默認值為"",也就是不限制網卡的訪問,但是Redis3.2中必須顯示的配置bind 0.0.0.0才可以達到這種效果。

    2. 建議

      經過上面的實驗以及對于bind的認識,可以得出如下結論:

      • 如果機器有外網IP,但是部署的Redis是給內部使用的,建議去掉外網網卡或者使用bind配置限制流量從外網進入。

      • 如果客戶端和Redis部署在一臺機器上,可以使用回環地址127.0.0.1。

      • bind配置不支持config set,所以盡可能在第一次啟動前配置好。

      如果當前Redis沒有配置密碼,沒有配置bind,那么只允許來自本機的訪問,也就是相當于配置了bind 127.0.0.1。

  5. 定期備份數據

    天有不測風云,假如有一天Redis真的被攻擊了(清理了數據,關閉了進程),那么定期備份的數據能夠在一定程度挽回一些損失,定期備份持久化數據是一個比較好的習慣。

  6. 不使用默認端口

    Redis的默認端口是6379,不使用默認端口從一定程度上可降低被入侵者發現的可能性,因為入侵者通常本身也是一些攻擊程序,對目標服務器進行端口掃描,例如MySQL的默認端口是3306、Memcache的默認端口11211、Jetty的默認端口8080等都會被設置成攻擊目標,Redis作為一款較為致知名的NoSQL服務,6379必然也在端口的掃毛的列表中,雖然不設置默認端口還是有可能被攻擊者入侵,但是能夠在一定程度上降低被攻擊的概率。

  7. 使用非root用戶啟動

    root用戶作為管理員,權限非常大。如果被入侵者獲取root權限后,就可以在這臺機器以及相關機器上“為所欲為”了。筆者建議在啟動Redis服務的使用使用非root用戶啟動。事實上許多服務,例如Resin、Jetty、HBase、Hadoop都建議使用非root啟動。

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,746評論 2 370

推薦閱讀更多精彩內容