12.3亡脑、安全的Redis

安全的Redis

2015年11月,全球數(shù)萬個Redis節(jié)點遭受到了攻擊邀跃,所有數(shù)據(jù)都會被清除了霉咨,只有一個叫crackit的鍵存在,這個鍵的值很像一個公鑰拍屑。

數(shù)據(jù)丟失對于很多Redis的開發(fā)者來說是致命的途戒,經(jīng)過相關機構的調查發(fā)現(xiàn),被攻擊的Redis有以下特點:

  • Redis所在的機器有外網(wǎng)IP

  • Redis以默認端口6379為啟動端口丽涩,并且是對外網(wǎng)開放的棺滞。

  • Redis是以root用戶啟動的

  • Redis沒有設置密碼

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

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

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

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

2)由于機器B的外網(wǎng)對外開通了Redis的6379端口,所以可以直接連接到Redis上執(zhí)行flushall操作猪瞬,注意此事破壞性已經(jīng)很大了憎瘸。

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

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

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

6)此時機器A再通過SSH協(xié)議訪問機器B皱埠,發(fā)現(xiàn)可以順利登錄肮帐,登錄后可以觀察/root/.ssh/authorized_keys,可以發(fā)現(xiàn)它就是RDB文件边器。

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

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

  1. Redis密碼機制

    1. 簡單的密碼機制

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

      redis-server --requirepass hello_redis_devpos

      此時通過redis-cli執(zhí)行命令會受到?jīng)]有權限的提示:

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

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

      • redis-cli -a參數(shù)翅娶。使用redis-cli連接Redis時,添加-a加密碼的參數(shù)好唯,如果密碼正確就可以正常訪問Redis了竭沫,具體操作如下:
      # redis-cli -h 127.0.0.1 -p 6379 -a hello_redis_devops
      127.0.0.1:6379> ping
      PONG
      
      • auth命令。通過redis-cli連接后骑篙,執(zhí)行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個字節(jié)以上)谎势,因為Redis的性能很高,如果密碼比較單間杨名,完全是可以在一段時間內通過暴力破解來破譯密碼脏榆。

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

      • auth是通過明文進行傳輸?shù)模砸膊皇?00%可靠,如果被攻擊者劫持也相當危險镊折。

  2. 偽裝危險命令

    1. 引入rename-command

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

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

      • flushall/flushdb:數(shù)據(jù)全部被清除赃泡。

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

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

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

      • shutdown:停止Redis。

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

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

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

      
      而如果執(zhí)行flushalltest牢贸,那么就可以實現(xiàn)flushall的功能了,這就是rename-command的作用镐捧,管理員可以對認為比較危險的命令做rename-command處理潜索。
      
      
    2. 沒有免費的午餐

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

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

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

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

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

    3. 最佳實踐

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

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

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

      • 如果涉及主從關系蜕企,一定要保持主從節(jié)點配置一致性咬荷,否則存在主從數(shù)據(jù)不一致的可能性。

  3. 防火墻

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

  4. bind

    1. 對于bing的錯誤認識

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

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

      • 內網(wǎng)地址:10.10.xx.192

      • 外網(wǎng)地址:220.181.xx.123

      • 回環(huán)地址:127.0.0.1

      如果當前Redis配置了bind 10.10.xx.192根灯,那么Redis訪問只能通過10.10.xx.192這塊網(wǎng)卡進入径缅,通過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的參數(shù)烙肺。

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

      bind 10.10.xx.192 127.0.0.1
      

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

    2. 建議

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

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

      • 如果客戶端和Redis部署在一臺機器上星著,可以使用回環(huán)地址127.0.0.1购笆。

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

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

  5. 定期備份數(shù)據(jù)

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

  6. 不使用默認端口

    Redis的默認端口是6379捌斧,不使用默認端口從一定程度上可降低被入侵者發(fā)現(xiàn)的可能性笛质,因為入侵者通常本身也是一些攻擊程序,對目標服務器進行端口掃描捞蚂,例如MySQL的默認端口是3306妇押、Memcache的默認端口11211、Jetty的默認端口8080等都會被設置成攻擊目標姓迅,Redis作為一款較為致知名的NoSQL服務敲霍,6379必然也在端口的掃毛的列表中,雖然不設置默認端口還是有可能被攻擊者入侵丁存,但是能夠在一定程度上降低被攻擊的概率肩杈。

  7. 使用非root用戶啟動

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

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末逾礁,一起剝皮案震驚了整個濱河市说铃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嘹履,老刑警劉巖腻扇,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異植捎,居然都是意外死亡衙解,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門焰枢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蚓峦,“玉大人舌剂,你說我怎么就攤上這事∈钜” “怎么了霍转?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長一汽。 經(jīng)常有香客問我避消,道長,這世上最難降的妖魔是什么召夹? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任岩喷,我火速辦了婚禮,結果婚禮上监憎,老公的妹妹穿的比我還像新娘纱意。我一直安慰自己,他們只是感情好鲸阔,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布偷霉。 她就那樣靜靜地躺著,像睡著了一般褐筛。 火紅的嫁衣襯著肌膚如雪类少。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天渔扎,我揣著相機與錄音硫狞,去河邊找鬼。 笑死赞警,一個胖子當著我的面吹牛妓忍,可吹牛的內容都是我干的。 我是一名探鬼主播愧旦,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼定罢!你這毒婦竟也來了笤虫?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤祖凫,失蹤者是張志新(化名)和其女友劉穎琼蚯,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惠况,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡遭庶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了稠屠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片峦睡。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡翎苫,死狀恐怖,靈堂內的尸體忽然破棺而出榨了,到底是詐尸還是另有隱情煎谍,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布龙屉,位于F島的核電站呐粘,受9級特大地震影響,放射性物質發(fā)生泄漏转捕。R本人自食惡果不足惜作岖,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望五芝。 院中可真熱鬧痘儡,春花似錦、人聲如沸与柑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽价捧。三九已至丑念,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間结蟋,已是汗流浹背脯倚。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嵌屎,地道東北人推正。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像宝惰,于是被迫代替她去往敵國和親植榕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內容