x forward for 取客戶端ip

2021-08-26 05:28:21 字數 3172 閱讀 6224

如今利用nginx做負載均衡的例項已經很多了,針對不同的應用場合,還有很多需要注意的地方,本文要說的就是在通過cdn 後到達nginx做負載均衡時請求頭中的x-forwarded-for項到底發生了什麼變化。下圖為簡單的web架構圖:

nginx 負載均衡

先來看一下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。我們可以通過php程式獲得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或者乾脆不設定!

參考文章:

另在不同的**情況下,其中x-forward-for的情況

對於這三個值:remote_addr、http_via、http_x_forwarded_for  來說,可以分以下五種情況:

一、沒有使用**伺服器的情況:

remote_addr = 您的 ip

http_via = 沒數值或不顯示

http_x_forwarded_for = 沒數值或不顯示

二、使用透明**伺服器的情況:transparent proxies

remote_addr = 最後乙個**伺服器 ip

http_via = **伺服器 ip

http_x_forwarded_for = 您的真實 ip ,經過多個**伺服器時,這個值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

這類**伺服器還是將您的資訊**給您的訪問物件,無法達到隱藏真實身份的目的。

三、使用普通匿名**伺服器的情況:anonymous proxies

remote_addr = 最後乙個**伺服器 ip

http_via = **伺服器 ip

http_x_forwarded_for = **伺服器 ip ,經過多個**伺服器時,這個值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

隱藏了您的真實ip,但是向訪問物件透露了您是使用**伺服器訪問他們的。

四、使用欺騙性**伺服器的情況:distorting proxies

remote_addr = **伺服器 ip

http_via = **伺服器 ip

http_x_forwarded_for = 隨機的 ip ,經過多個**伺服器時,這個值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

告訴了訪問物件您使用了**伺服器,但編造了乙個虛假的隨機ip代替您的真實ip欺騙它。

五、使用高匿名**伺服器的情況:high anonymity proxies (elite proxies)

remote_addr = **伺服器 ip

http_via = 沒數值或不顯示

http_x_forwarded_for = 沒數值或不顯示 ,經過多個**伺服器時,這個值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

完全用**伺服器的資訊替代了您的所有資訊,就象您就是完全使用那台**伺服器直接訪問物件。

瘦客戶端 胖客戶端 智慧型客戶端

胖客戶端模式將應用程式處理分成了兩部分 由使用者的桌面計算機執行的處理和最適合乙個集中的伺服器執行的處理。乙個典型的胖客戶端包含乙個或多個在使用者的pc上執行的應用程式,使用者可以檢視並運算元據 處理一些或所有的業務規則 同時提供乙個豐富的使用者介面做出響應。伺服器負責管理對資料的訪問並負責執行一些...

取客戶端MAC位址方法

一 後台通過ip去mac位址 1.獲取客戶端ip位址 這個必須從客戶端傳到後台 jsp頁面下,很簡單,request.getremoteaddr 因為系統的view層是用jsf來實現的,因此頁面上沒法直接獲得類似request,在bean裡做了個強制轉換 public string getmyip ...

胖客戶端 瘦客戶端和富客戶端

以c s結構開發的網路應用程式,需要為客戶端開發專用的客戶端軟體,相對而言其客戶端比較龐大,在客戶端可以實現很多功能,分擔伺服器的負擔,屬於胖客戶端型別。以b s結構開發的web應用,其客戶端只是乙個瀏覽器,所有業務邏輯由伺服器端進行處理,相對而言客戶端比較瘦小,故稱為瘦客戶端。目前比較流行的一種開...