X Forwarded For 的一些理解

2021-09-08 13:56:49 字數 3224 閱讀 8754

x-forwarded-for 是乙個 http 擴充套件頭部,

主要是為了讓 web 伺服器獲取訪問使用者的真實 ip 位址(其實這個真實未必是真實的,後面會說到)。

那為什麼 web 伺服器只有通過 x-forwarded-for 頭才能獲取真實的 ip?

x-forwarded-for: client1, proxy1, proxy2

解決方案:

if(!stringutils.isempty(ip)) 

*****==

這裡用 php 語言來說明,不明白原理的開發者為了獲取客戶 ip,會使用 $_server['remote_addr'] 變數,這個伺服器變數表示和 web 伺服器握手的 ip 是什麼(這個不能偽造)。

但是很多使用者都通過**來訪問伺服器的,那麼假如使用該全域性變數,php獲取到的 ip 就是**伺服器的 ip(不是使用者的)。

可能很多人看的暈乎乎的,那麼看看乙個請求可能經過的路徑:

客戶端=>(正向**=>透明**=>伺服器反向**=>)web伺服器
其中正向**、透明**、伺服器反向**這三個環節並不一定存在。

現在假設幾種情況:

其實這裡的知識點很多,記住一點就行了,$_server['remote_addr'] 獲取到的 ip 是 web 伺服器 tcp 連線的 ip(這個不能偽造,一般 web 伺服器也不會修改這個頭)。

x-forwarded-for

從上面大家也看出來了,因為有了各種**,才會導致 remote_addr 這個全域性變數產生了一定的歧義,為了讓 web 伺服器獲取到真實的客戶端 ip,x-forwarded-for 出現了,

這個協議頭也是由 squid 起草的(squid 應該是最早的**軟體之一)。

這個協議頭的格式:

x-forwarded-for: client, proxy1, proxy2
client 表示使用者的真實 ip,每經過一次**伺服器,**伺服器會在這個頭增加使用者的 ip(有點拗口)。

注意最後乙個**伺服器請求 web 伺服器的時候是不會將自己的 ip 附加到 x-forwarded-for 頭上的,最後乙個**伺服器的 ip 位址應該通過$_server['remote_addr']獲取。

舉個例子:

使用者的 ip 為(a),分別經過兩個**伺服器(b,c),最後到達 web 伺服器,那麼web 伺服器接收到的 x-forwarded-for 就是 a,b。

那麼 php 如何獲取真實客戶端 ip 呢?

這裡預先說明下,假設這兩個**伺服器都是好的**伺服器,沒有偽造 http_x_forwarded_for。

配置反向**

上面一直在說**,大家可能覺得這到底有啥用?不同型別的**有不同的目的,對於正向**來說主要是為了加速並且讓區域網的使用者有乙個真實的 ip 位址,而透明**則主要是為了一些其他的目的(比如就是不想讓別人知道我的 ip),而反向**主要是企業內部安全和負載均衡考慮,這裡主要說下如何配置反向**。

現在只要是具備一定規模的**(web 伺服器大於 1 臺),為了安全和負載均衡考慮都會在 web 伺服器前面部署反向**,反向**有 haproxy,nginx,apache 等等。

這裡通過 nginx 來部署反向**:

簡單的解釋下:

apache web 伺服器的 access 日誌如何獲取 x-forwarded-for 頭

其實寫這篇文章主要是因為自己在 apache web 伺服器上獲取不到 x-forwarded-for(上層的負載均衡裝置確定傳遞了),搜尋了下(在 apache 官方文件並沒有找到解決方案),解決如下:

logformat "%i %a %h %a %l %u %t \"%r\" %>s %b \"%i\"

\"%i\"" combined

x-forwarded-for 安全性

那麼很多同學會說,通過 x-forwarded-for 就能獲取到使用者的真實 ip,是不是萬事大吉了,對於 web 伺服器來說,安全有兩個緯度,第乙個緯度是 remote_addr 這個頭,這個頭不能偽造。第二個緯度就是 x-forwarded-for,但是這個頭是可以偽造的。

那麼誰在偽造呢?,我們分別看下:

正向**一般是公司加速使用的,假如沒有特殊的目的,不應該傳遞 x-forwarded-for 頭,因為它的上層連線是內部 ip,不應該暴露出去,當然它也可以透明的傳遞這個頭的值(而這個值使用者可以偽造)。

透明**,這個可能是使用者自己搭建的(比如fq),而且在乙個使用者的請求中,可能有多個透明**,這時候透明**就抓瞎了,為了讓自己盡量的正確,也會透明的傳遞這個頭的值(而這個值使用者可以偽造),當然一些不法企業或者人員,為了一些目的,會改下這個頭的值(比如來自世界各地的 ip 位址)。

反向**,web 伺服器前的反向**伺服器是不會偽造的(同乙個公司的),一般會原樣傳遞這個頭的值。

那麼對應用程式來說,既然這個值不能完全相信,該怎麼辦呢?這取決於應用的性質:

假如提供的服務可能就是一些非機密服務,也不需要知道使用者的真實 ip,那麼建議應用程式或者 web 伺服器對 remote_addr 做一些限制,比如進行限速等等,也可以放行一些白名單的** ip,但是這些白名單 ip 就太難衡量了。

假設你的服務很重要,比如**(乙個 ip 只能一次**),這時候你可能想通過 x-forwarded-for 來獲取使用者的真實 ip(假如使用 remote_addr 則會誤殺一片),但是由於 x-forwarded-for 可能會偽造,所以其實並沒有什麼好的辦法,只能在應用層進行處理了。

x forwarded for的深度挖掘

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

X Forwarded For注入漏洞

測試思路 1 登入後台提示ip資訊不正確,這種情況一般是x forwarded for讀取客戶端ip 2 通過在資料報新增x forwarded for 1.1.1.1看 respone包中是否存在1.1.1.1 3 如果存在則證明用x forwarded for讀取客戶端資料,則存在注入漏洞 4 ...

Denoise auto encoder的乙個理解

這幾天反覆的看denoise auto encoder的解釋,尤其是geometric interpretation。作者寫道,本來的資料假定是在乙個低緯度的流行結構上,加了噪音之後,這些噪音點就距離這個流行結構要有點遠,或者不在這個流行結構上了,那麼學習的過程就會去學習在這個本來的流行結構。個人認...