X-Forwarded-For的一些理解(1)
文章目錄
##關於X-Forwarded-For的簡要概述
X-Forwarded-For 是一個 HTTP 擴充套件頭部,主要是為了讓 Web 伺服器獲取訪問使用者的真實 IP 地址,但是這個IP卻未必是真實的,我們後面會回來描述這個問題。一些開發者為了獲取客戶IP,我們經常會使用request.remote_ip來獲得使用者IP。但是很多使用者都是通過代理來訪問伺服器的,如果使用remote_ip這個全域性變數來獲取IP,開發者往往獲得的是代理伺服器的IP,並不是使用者真正的IP。
客戶端=>正向代理=>透明代理=>伺服器反向代理=>Web伺服器 |
假如客戶端直接連線 Web 伺服器(假設 Web 伺服器有公網地址),則 request.remote_ip獲取到的是客戶端的真實 IP 。
假設 Web 伺服器前部署了反向代理(比如 Nginx),則 request.remote_ip獲取到的是反向代理裝置的 IP(Nginx)。
假設客戶端通過正向代理直接連線 Web 伺服器(假設 Web 伺服器有公網地址),則request.remote_ip獲取到的正向代理裝置的 IP 。
其實這裡的知識點很多,記住一點就行了,request.remote_ip獲取到的 IP 是 Web 伺服器 TCP 連線的 IP(這個不能偽造,一般 Web 伺服器也不會修改這個頭)。
##關於X-Forwarded-For的一個思考
我們都知道,Http是基於Tcpip的協議,我們為什麼不可以從傳輸層的socket獲得我們所需要源使用者ip呢?其實Http已經從socket取得所需要IP,但是這個IP並一定是我們所需要的真實IP,來看看下面的兩個例子。
在第一個例子中,我們可以看出來,客戶端是直接連結的伺服器,則獲取到的IP即為真實的client ip地址資訊。
若通過代理, 則直連的ip會被代理伺服器的ip所替代。通過兩個例子中的對比, 我們可以清楚的觀察到, 在反向代理模式下, 客戶端的socket已經被nginx的socket所代替。若還是按預設的方式來獲取客戶端ip, 將失去意義。在這裡,基本可以回答我們疑惑了,但是我們可以再往下探究一下,http的請求經過了nginx,我們是怎麼從X-Forwarded-For中獲得我們真實的IP。
##nginx配置
nginx是7層代理, 不是4層代理。7層代理的意思我們只能從修改第七層的包資訊,因此不可能在tcp/ip這層做手腳. 只能在http/https這個應用層協議中做文章。nginx的策略是: 往http/https請求中, 新增額外的header資訊, 以此來完成真實客戶端ip的資訊傳遞。下面是nginx中的一些內部變數的定義:
$remote_addr #來自對端socket的ip地址
$remote_port #來自對端socket的port資訊
$proxy_add_x_forwarded_for #http/https請求流經的所有代理的ip
在nginx配置中, 需要在location標籤下新增如下項:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
X-Real-IP我們很容易可以理解了,就是取得和我們伺服器建立tcp連結的ip地址。這裡就需要X-Forwarded-For來記錄ip的資訊了。
標準格式如下:X-Forwarded-For: client1, proxy1, proxy2。從標準格式可以看出,X-Forwarded-For頭資訊可以有多個,中間用逗號分隔,第一項為真實的客戶端ip,剩下的就是曾經經過的代理或負載均衡的ip地址,經過幾個就會出現幾個。
光從定義來看, X-Forward-For只是記錄了, 來自客戶端所流經的代理伺服器的鏈路路程, 好像沒啥作用. 獲取真實IP, 通過獲取設定的X-Real-IP即可。當nginx只有一層代理,這種方案是可行的。
但是在現實的web架構中, 存在多層代理伺服器時, 使用X-Real-IP會丟失真實的客戶端IP, 而X-Forward-For依舊為你保留了真實的客戶端IP, 這也為什麼後端web server從X-Forward-For中獲取client ip, 而不是從X-Real-IP中獲取的本質原因。
##總結
這是一篇比較淺顯的部落格,目的只是為了可以更好理解X-Forwarded-For的使用場景,以及結合nginx使用可以產生的效果。後面如果還有更深入的思考,會繼續寫下去。
相關文章
- HTTP 請求頭中的 X-Forwarded-ForHTTPForward
- HTTP X-Forwarded-For是什麼?HTTPForward
- JSON的一些理解JSON
- orion使用的一些理解
- X-Forwarded-For 和 X-Real-IP 的區別?Forward
- 分散式鎖的一些理解分散式
- 關於position的一些理解
- 對ThreadLocal的一些理解thread
- Express原始碼的一些理解Express原始碼
- 對React一些原理的理解React
- React事務的一些理解React
- flutter中的rebuild一些理解FlutterRebuild
- c++ typedef的一些理解C++
- map底層的一些理解
- 對於Fragment的一些理解Fragment
- 對運營的一些理解
- 對synchronized(this)的一些理解(轉)synchronized
- 對Transformer的一些理解ORM
- 一些八股:1.fetch 的理解。2.let、const、var
- 《Python 原始碼剖析》一些理解以及勘誤筆記(1)Python原始碼筆記
- 關於position定位的一些理解
- lucene(一) lucene一些概念的理解
- 差分約束的一些理解
- 通俗理解一些概念
- java 繼承多型的一些理解和不理解Java繼承多型
- 關於Dart中Future的一些理解Dart
- 關於Swift中Properties的一些理解Swift
- 對於Redux原始碼的一些理解Redux原始碼
- new static ,new self ,self::, $this的一些理解
- 關於Base64的一些理解
- JS Array.prototype.reduce的一些理解JS
- 對於最近的一些理解和思考
- NIO系列1:Channel的理解
- webpack (1)——核心概念的理解Web
- 1. 對Vue的理解Vue
- redux中介軟體的原始碼的一些理解Redux原始碼
- 最近的一些心得以及Soma框架的理解框架
- 關於服務高可用的一些理解