F5轉包時將請求IP記錄到X-Forwarded-For字段
最近在做某個系統的安全加固的時候,發現tomcat記錄的日志全部來自於F5轉發的IP地址,不能獲取到請求的真實IP。
經過抓包分析,F5在轉發請求包的時候會將來源IP記錄在HTTP包header中的X-Forwarded-For字段,如下圖是用wireshark(www.wireshark.org/download.html)截取的包。
而Tomcat是在tomcat/conf/server.xml中配置日志選項的:
Tomcat如何記錄日志
禁用<AccessLogValue>,則對應logs目錄下不會生成localhost_access_log.txt
Logs下沒有localhost_access_log.txt見:
當開啟<AccessLogValue>,則會有localhost_access_log.txt日志記錄請求來源
當配置中的pattern=common時,對應的日志是如下,無論正常請求和非法請求都會記錄。
記錄遠程IP的兩個方法
方案1
修改pattern為pattern='%{X-Forwarded-For}i %h %l %u %t "%r" %s %b',則會記錄headers頭中的X-Forwarded-For信息
如果沒有則記錄為空,如下
驗證:用fiddle構造有X-Forwarded-For的請求包
原始請求
構造X-Forwarded-For字段
服務器localhost_access_log.txt
方案2
不修改pattern,增加RemoteIpValue配置
前兩個是記錄X-Forworded-For,后面是沒有X-Forwarded-For,說明是有效的
以上的這些都參考了相關文檔,下面這些才是實驗。
方案比較
比較1:如果有X-Forwarded-For頭,但是內容為空。
方案1顯示空和轉發IP
方案2顯示直接來源IP
比較2:多個X-Forwarded-For字段
例如一個包里面有兩個X-Forwarded-For字段
X-Forwarded-For:59.66.156.24
X-Forwarded-For:59.66.156.111
方案1日志為(記錄第一個):59.66.156.24 192.168.1.58 - - [12/Dec/2012:22:56:54 +0800] "GET /docs/ HTTP/1.1" 304 -
方案2日志為(記錄第一個):59.66.156.24 - - [12/Dec/2012:22:50:16 +0800] "GET /docs/ HTTP/1.1" 304 –
比較3:X-Forwarded-For有多個IP
例如:X-Forwarded-For:59.66.156.24,59.66.156.111
方案1日志為顯示完整X-Forwarded-For字段信息:
59.66.156.24,59.66.156.111 192.168.1.58 - - [12/Dec/2012:22:58:01 +0800] "GET /docs/ HTTP/1.1" 304 -
方案2日志記錄為(記錄最后一個IP):
59.66.156.111 - - [12/Dec/2012:22:53:51 +0800] "GET /docs/ HTTP/1.1" 304 -
結論
方案1真實反映X-Forwarded-For字段(無論有無IP,有多少個IP),並且以header頭按順序讀取,顯示讀取到第一個X-Forwarded-For。
方案2試圖將IP進行來源替換,如果有X-Forwarded-For字段,則顯示最后一個IP,否則顯示直接IP
因此從日志記錄來看,方案1的信息量更為大。
遺留問題
如果有人偽造了多個X-Forwarded-For字段,而F5轉包時,到底會將請求IP加到那個X-Forwarded-For字段呢?我只能寄希望於他會在第一個X-Forwarded-For中添加這個信息,否則tomcat就無法記錄了。
參考資料
http://tomcat.apache.org/tomcat-6.0-doc/config/valve.html
http://www.techstacks.com/howto/configure-access-logging-in-tomcat.html