古詩詞大全網 - 四字成語 - X-Forwarded-For缺陷與陷阱

X-Forwarded-For缺陷與陷阱

X-Forwarded-For:簡稱XFF頭,它代表客戶端,也就是HTTP的請求端真實的IP,只有在通過了HTTP 代理或者負載均衡服務器時才會添加該項。它不是RFC中定義的標準請求頭信息,在squid緩存代理服務器開發文檔中可以找到該項的詳細介紹。

X-Forwarded-For(XFF)是用來識別通過HTTP代理或負載均衡方式連接到Web服務器的客戶端最原始的IP地址的HTTP請求頭字段。 Squid 緩存代理服務器的開發人員最早引入了這壹HTTP頭字段,並由IETF在Forwarded-For HTTP頭字段標準化草案中正式提出。

這壹HTTP頭壹般格式如下:

X-Forwarded-For: client1, proxy1, proxy2, proxy3

其中的值通過壹個 逗號+空格 把多個IP地址區分開, 最左邊(client1)是最原始客戶端的IP地址, 代理服務器每成功收到壹個請求,就把請求來源IP地址添加到右邊。 在上面這個例子中,這個請求成功通過了3臺代理服務器:proxy1, proxy2 及 proxy3。請求由client1發出,到達了proxy3(proxy3可能是請求的終點)。請求剛從client1中發出時,XFF是空的,請求被發往proxy1;通過proxy1的時候,client1被添加到XFF中,之後請求被發往proxy2;通過proxy2的時候,proxy1被添加到XFF中,之後請求被發往proxy3;通過proxy3時,proxy2被添加到XFF中,之後請求的的去向不明,如果proxy3不是請求終點,請求會被繼續轉發。

因為偽造這壹字段非常容易,所以應該謹慎使用X-Forwarded-For字段。正常情況下XFF中最後壹個IP地址是最後壹個代理服務器的IP地址, 這通常是壹個比較可靠的信息來源。下面會詳細說明,在什麽情況下,這個信息並不準確。

如果客戶端使用了http代理(壹般大公司內部上網都需要使用代理),同時,這個代理並沒有正確設置(也可能是故意不設置)XFF,那麽,XFF中client1的位置就會被http代理的ip取代,那麽我們就無法正確獲取客戶端的真實IP。

為了減緩可用的IP地址空間的枯竭, 大多數ISP網絡或者公司網絡中都會使用NAT設備,這樣,壹個公司或者壹個小區的用戶就可以***享使用壹個IP來實現上網需求。NAT設備工作在IP層和TCP層,所以XFF不管怎麽設置也無法解決這個問題。

這種情況下,我們也無法拿到客戶的真實IP。

Windows:

Linux

訪問以下兩個網址,返回的網頁會告訴妳,妳的公網IP是多少

可以用curl訪問網址,舉個例子

結果,我的真實ip是192.168.1.186(私有IP),但是在XFF中會顯示我的IP為223.72.90.206。

有的公司使用 加速樂 , 我們可以認為使用這種服務後,相當於增加了壹層http代理。

我們可以查看壹下域名是否使用了加速樂(查看其他的安全服務也是類似的方法)

結果,XFF中有壹層proxy就是加速樂的IP,由於加速樂有很多節點,所以這個IP地址新並不是固定的。內部消息顯示加速樂節點的IP要達到上萬個,盡管我太想相信。但是這至少說明壹點,就是XFF中proxy的IP地址是多變的。

最近測試發現,使用電信4G網絡的時候,XFF會莫名其妙的加入多個proxy代理,但是這個IP地址實在是無法查證,我們姑且認為他們也是壹種安全服務吧

攻擊者可以很容易偽造XFF,在發出請求時在XFF值中插入多個IP地址,以混淆服務端獲取到客戶端的真實IP。

結論,從XFF中的獲取到的客戶端IP地址並不可信,在使用各種ACL策略的時候,需要讀者權衡利弊來滿足業務需求。

nginx目前在各個互聯網公司中的標配, 其中ngx_http_realip_module模塊就提供從XFF中實現獲取用戶的真實IP的功能。

但是,上面的配置有壹些問題,妳發現什麽問題了嗎?

首先,我們解釋壹下上面最後壹條配置語句的含義

實際上的含義是

我們可以看到, X-Forwarded-For加上$remote_addr。但是有壹個問題,realip模塊要比proxy模塊運行的早,在realip模塊中會把remote_addr重置為客戶端IP,這樣會導致 X-Forwarded-For設置錯誤。

我們拿proxy3為例,正常情況下,XFF傳到proxy4服務時,XFF的值是

如果按照上面的配置的話,XFF值會是

如果內部有兩級Nginx的話,XFF值會是

總之,只要是XFF出現的重復的IP地址,就有理由懷疑是Nginx配置引起的。

下面是才是realip的正確配置

remote_addr的副本信息,當realip模塊修改了 realip_remote_addr用於保留$remote_addr的原始值。

假設有這樣壹個XFF

其中,如果proxy2,proxy3是我們已知(可信)代理的話,我們可以確定proxy1的IP地址是可信的。