s
https://en.wikipedia.org/wiki/X-Forwarded-For
http://www.cnblogs.com/yihang/archive/2010/12/19/1910365.html
問題表象1:
攔截量從5點開始增多,從日志看是因為請求中x_forwarded_for字段為空,導致WAF獲取不到用戶的IP,WAF會將所有未獲取到IP的請求當成同一個人發起,超過頻率限制被攔截
分析問題1:
web訪問軟防火牆安全規則1:如果一個用戶連續兩次請求之前時間間隔不大於1秒,算1次;
web訪問軟防火牆安全規則2:B2C分區設置的每分鍾一個用戶此種情況攔截閾值為4200,除以集群系數,每台防火牆服務器上每分鍾一個用戶此種情況超過70次就會攔截。
解決問題1:
數據鏈路:用戶 -- > CDN -- > F5 VIP(無配置x_forwarded_for導致) --> WAF(誤認為同一IP,觸發封禁規則) --> B2C 主站。
解決方法1
數據鏈路:用戶 -- > CDN -- > F5 VIP(無配置x_forwarded_for導致) --> WAF(同一F5 VIP設置白名單,臨時解禁規則) --> B2C 主站。
解決方法2
數據鏈路:用戶 -- > CDN -- > F5 VIP(配置x_forwarded_for) --> WAF(不再認為同一VIP F5設備,終極解決) --> B2C 主站。
先來看一下X-Forwarded-For的定義:
X-Forwarded-For:簡稱XFF頭,它代表客戶端,也就是HTTP的請求端真實的IP,只有在通過了HTTP 代理或者負載均衡服務器時才會添加該項。它不是RFC中定義的標准請求頭信息,在squid緩存代理服務器開發文檔中可以找到該項的詳細介紹。
標准格式如下:
X-Forwarded-For: client1, proxy1, proxy2
從標准格式可以看出,X-Forwarded-For頭信息可以有多個,中間用逗號分隔,第一項為真實的客戶端ip,剩下的就是曾經經過的代理或負載均衡的ip地址,經過幾個就會出現幾個。
按照上圖的Web架構圖,可以很容易的看出,當用戶請求經過CDN后到達Nginx負載均衡服務器時,其X-Forwarded-For頭信息應該為 客戶端IP,CDN的IP 但實際情況並非如此,一般情況下CDN服務商為了自身安全考慮會將這個信息做些改動,只保留客戶端IP。我們可以通過程序獲得X-Forwarded-For信息或者通過Nginx的add header方法來設置返回頭來查看。
下面來分析請求頭到達Nginx負載均衡服務器的情況;在默認情況下,Nginx並不會對X-Forwarded-For頭做任何的處理,除非用戶使用proxy_set_header 參數設置:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
$proxy_add_x_forwarded_for變量包含客戶端請求頭中的"X-Forwarded-For",與$remote_addr用逗號分開,如果沒有"X-Forwarded-For" 請求頭,則$proxy_add_x_forwarded_for等於$remote_addr。
$remote_addr變量的值是客戶端的IP
當Nginx設置X-Forwarded-For等於$proxy_add_x_forwarded_for后會有兩種情況發生
1、如果從CDN過來的請求沒有設置X-Forwarded-For頭(通常這種事情不會發生),而到了我們這里Nginx設置將其設置為$proxy_add_x_forwarded_for的話,X-Forwarded-For的信息應該為CDN的IP,因為相對於Nginx負載均衡來說客戶端即為CDN,這樣的話,后端的web程序時死活也獲得不了真實用戶的IP的。
2、CDN設置了X-Forwarded-For,我們這里又設置了一次,且值為$proxy_add_x_forwarded_for的話,那么X-Forwarded-For的內容變成 ”客戶端IP,Nginx負載均衡服務器IP“如果是這種情況的話,那后端的程序通過X-Forwarded-For獲得客戶端IP,則取逗號分隔的第一項即可。
如上兩點所說,如果我們知道了CDN設置了X-Forwarded-For信息,且只有客戶端真實的IP的話,那么我們的Nginx負載均衡服務器可以不必理會該頭,讓它默認即可。
其實Nginx中還有一個$http_x_forwarded_for變量,這個變量中保存的內容就是請求中的X-Forwarded-For信息。如果后端獲得X-Forwarded-For信息的程序兼容性不好的話(沒有考慮到X-Forwarded-For含有多個IP的情況),最好就不要將X-Forwarded-For設置為 $proxy_add_x_forwarded_for。應該設置為$http_x_forwarded_for或者干脆不設置!
end