標籤:
一、安全
Redis的作者Salvatore Sanfilippo曾經發表過Redis宣言,其中提到Redis以簡潔為美。同樣在安全層面Redis也沒有做太多的工作。
1、可信的環境
Redis的安全設計是在“Redis運行在可信環境”這個前提下做出的,在生產環境運行時不能允許外界直接連接到Redis伺服器上,而應該通過應用程式進行中轉,運行在可信的環境中是保證Redis安全的最重要方法。
Redis的預設配置會接受來自任何地址發送來的請求,即在任何一個擁有公網IP的伺服器上啟動Redis伺服器,都可以被外界直接存取到。要更改這一設定,在設定檔中修改bind參數,如只允許本機應用串連Redis,可以將bind參數改成:
[html] view plaincopyprint?
- bind 127.0.0.1
bind參數只能綁定一個地址。如果想更自由地設定訪問規則需要通過防火牆來完成。
注釋:Redis可能會在2.8版本中支援綁定多個地址,參見https://github.com/antirez/redis/issues/274。
2、資料庫密碼
除此之外,還可以通過設定檔中的requirepass參數為Redis設定一個密碼。例如:
[html] view plaincopyprint?
- requirepass TAFK(@~!ji^XALQ(sYh5xIwTn5Ds7JF
用戶端每次串連到Redis時都需要發送密碼,否則Redis會拒絕執行用戶端發來的命令。例如:
[html] view plaincopyprint?
- redis>GET foo
- (error)ERR operation not permitted
發送密碼需要使用AUTH命令,就像這樣:
[html] view plaincopyprint?
- AUTH TAFK(@~!ji^XALQ(sYh5xIwTn5Ds7JF
- OK
之後就可以執行任何命令了:
[html] view plaincopyprint?
- redis>GET foo
- "1"
由於Redis的效能極高,並且輸入錯誤密碼後Redis並不會進行主動延遲(考慮到Redis的單執行緒模式),所以攻擊者可以通過窮舉法破解Redis的密碼(1秒內能夠嘗試十幾萬個密碼),因此在設定時一定要選擇複雜的密碼。
配置Redis複製的時候如果主要資料庫設定了密碼,需要在從資料庫的設定檔中通過masterauth 參數設定主要資料庫的密碼,以使從資料庫連接主要資料庫時自動使用AUTH命令認證。
3、命名命令
Redis支援在設定檔中將命令重新命名,比如將FLUSHALL 命令重新命名成一個比較複雜的名字,以保證只有自己的應用可以使用該命令。就像這樣:
[html] view plaincopyprint?
- rename-command FLUSHALL oyfekmjvmwxq5a9c8usofuo369x0it2k
如果希望直接禁用某個命令可以將命令重新命名成Null 字元串:
[html] view plaincopyprint?
- rename-command FLUSHALL ""
注意:無論設定密碼還是重新命名命令,都需要保證設定檔的安全性,否則就沒有任何意義了。
二、 通訊協定
Redis通訊協定是Redis用戶端與Redis之間交流的語言,通訊協定規定了命令和傳回值的格式。瞭解Redis通訊協定後不僅可以理解AOF檔案的格式和主從複製時主要資料庫向從資料庫發送的內容等,還可以開發自己的Redis用戶端(不過由於幾乎所有常用的語言都有相應的Redis用戶端,需要使用通訊協定直接和Redis打交道的機會確實不多)。
Redis支援兩種通訊協定,一種是二進位安全的統一請求協議(unified request protocol),一種是比較直觀的便於在telnet程式中輸入的簡單協議。這兩種協議只是命令的格式有區別,命令傳回值的格式是一樣的。
1、簡單協議
簡單協議適合在telnet程式中和Redis通訊。簡單協議的命令格式就是將命令和各個參數使用空格分隔開,如“EXISTS foo”、“SET foo bar”等。由於Redis解析簡單協議時只是簡單地以空格分隔參數,所以無法輸入二進位字元。我們可以通過telnet程式測試:
[html] view plaincopyprint?
- telnet 127.0.0.1 6379
- Trying 127.0.0.1...
- Connected to localhost.
- Escape character is ‘^]‘ .
- SET foo bar
- +OK
- GET foo
- $3
- bar
- LPUSH plist 1 2 3
- :3
- LRANGE plist 0 -1
- *3
- $1
- 3
- $1
- 2
- $1
- 1
- ERRORCOMMAND
- -ERR unknown command ‘ERRORCOMMAND‘
Redis 2.4之前的版本對於某些命令可以使用類似簡單協議的特殊方式輸入二進位安全的參數,例如:
[html] view plaincopyprint?
- C:SET foo 3
- C:bar
- S:+OK
其中C:表示用戶端發出的內容,S:表示服務端發出的內容。第一行的最後一個參數表示字串的長度,第二行是字串的實際內容,因為指定了長度,所以第二行的字串可以包含二進位字元。但是這個協議已經廢棄,被新的統一請求協議取代。“統一”二字指所有的命令使用同樣的請求方式而不再為某些命令使用特殊方式,如果需要在參數中包含二進位字元應該使用統一請求協議。
我們在telnet程式中輸入的5條命令恰好展示了Redis的5種傳回值類型的格式,之前展現形式是經過了redis-cli封裝的,而上面的內容才是Redis真正返回的格式。下面分別介紹。
(1)錯誤回複
錯誤回複(error reply )以-開頭,並在後面跟上錯誤資訊,最後以\r\n 結尾:
[html] view plaincopyprint?
- -ERR unknown command ‘ERRORCOMMAND‘\r\n
(2)狀態回複
狀態回複(status reply )以+開頭,並在後面跟上狀態資訊,最後以\r\n 結尾:
[html] view plaincopyprint?
- +OK\r\n
(3)整數回複
整數回複(integer reply )以:開頭,並在後面跟上數字,最後以\r\n 結尾:
[html] view plaincopyprint?
- :3\r\n
(4)字串回複
字串回複(bulk reply )以$開頭,並在後面跟上字串的長度,並以\r\n 分隔,接著是字串的內容和\r\n :
[html] view plaincopyprint?
- $3\r\nbar\r\n
如果傳回值是空結果nil,則會返回$-1以和Null 字元串相區別。
(5)多行字串回複
多行字串回複(multi-bulk reply )以*開頭,並在後面跟上字串回複的組數,並以\r\n 分隔。接著後面跟的就是字串回複的具體內容了:
[html] view plaincopyprint?
- *3\r\n1\r\n3\r\n1\r\n2\r\n1\r\n1\r\n
2、 統一請求協議
統一請求協議是從Redis 1.2開始加入的,其命令格式和多行字串回複的格式很類似,如SET foo bar的統一請求協議寫法是“*3\r\n3\r\nSET\r\n3\r\nfoo\r\n3\r\nbar\r\n ”。還是使用telnet進行示範:
[html] view plaincopyprint?
- telnet 127.0.0.1 6379
- Trying 127.0.0.1...
- Connected to localhost.
- Escape character is ‘^]‘ .
- *3
- $3
- SET
- $3
- foo
- $3
- bar
- +OK
- http://www.youyuanapp.com/thread-11419-1-1.html
http://www.youyuanapp.com/thread-11418-1-1.html
http://www.youyuanapp.com/thread-11417-1-1.html
http://www.youyuanapp.com/thread-11412-1-1.html
http://www.youyuanapp.com/thread-11409-1-1.html
http://www.youyuanapp.com/thread-11404-1-1.html
http://www.youyuanapp.com/thread-11403-1-1.html
http://www.youyuanapp.com/thread-11398-1-1.html
http://www.youyuanapp.com/thread-11397-1-1.html
http://www.youyuanapp.com/thread-11395-1-1.html
http://yishujiayuanq.blog.163.com/blog/static/2447250612015025101147963/
http://yishujiayuanq.blog.163.com/blog/static/2447250612015025101251829/
http://yishujiayuanq.blog.163.com/blog/static/244725061201502510133740/
http://yishujiayuanq.blog.163.com/blog/static/2447250612015025101653328/
http://yishujiayuanq.blog.163.com/blog/static/2447250612015025101718995/
http://yishujiayuanq.blog.163.com/blog/static/2447250612015025101738627/
http://yishujiayuanq.blog.163.com/blog/static/2447250612015025101822599/
http://yishujiayuanq.blog.163.com/blog/static/2447250612015025101841318/
http://yishujiayuanq.blog.163.com/blog/static/2447250612015025101927982/
http://yishujiayuanq.blog.163.com/blog/static/244725061201502510197287/
Redis研究(十三)—安全和通訊協定