X-Forwarded-For的一些理解

來源:互聯網
上載者:User

標籤:keyword   number   attr   加速   str   官方文檔   文章   client   協議   

X-Forwarded-For 是一個 HTTP 擴充頭部,主要是為了讓 Web 服務器擷取訪問使用者的真實 IP 位址(其實這個真實未必是真實的,後面會說到)。

那為什麼 Web 服務器只有通過 X-Forwarded-For 頭才能擷取真實的 IP?
這裡用 PHP 語言來說明,不明白原理的開發人員為了擷取客戶 IP,會使用 $_SERVER[‘REMOTE_ADDR‘] 變數,這個伺服器變數表示和 Web 服務器握手的 IP 是什麼(這個不能偽造)。
但是很多使用者都通過代理來訪問伺服器的,那麼假如使用該全域變數,PHP擷取到的 IP 就是Proxy 伺服器的 IP(不是使用者的)。

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

用戶端=>(正向 Proxy=>透明代理=>伺服器反向 Proxy=>)Web伺服器

其中正向 Proxy、透明代理、伺服器反向 Proxy這三個環節並不一定存在。

  • 什麼是正向 Proxy呢,很多企業會在自己的出口網關上設定代理(主要是為了加速和節省流量)。
  • 透明代理可能是使用者自己設定的代理(比如為了FQ,這樣也繞開了公司的正向 Proxy)。
  • 伺服器反向 Proxy是部署在 Web 服務器前面的,主要原因是為了負載平衡和安全考慮。

現在假設幾種情況:

  • 假如用戶端直接連接 Web 服務器(假設 Web 服務器有公網地址),則 $_SERVER[‘REMOTE_ADDR‘] 擷取到的是用戶端的真實 IP 。
  • 假設 Web 服務器前部署了反向 Proxy(比如 Nginx),則 $_SERVER[‘REMOTE_ADDR‘] 擷取到的是反向 Proxy裝置的 IP(Nginx)。
  • 假設用戶端通過正向 Proxy直接連接 Web 服務器(假設 Web 服務器有公網地址),則 $_SERVER[‘REMOTE_ADDR‘] 擷取到的正向 Proxy裝置的 IP 。

其實這裡的知識點很多,記住一點就行了,$_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,每經過一次Proxy 伺服器,Proxy 伺服器會在這個頭增加使用者的 IP(有點拗口)。
注意最後一個Proxy 伺服器請求 Web 服務器的時候是不會將自己的 IP 附加到 X-Forwarded-For 頭上的,最後一個Proxy 伺服器的 IP 位址應該通過$_SERVER[‘REMOTE_ADDR‘]擷取。

舉個例子:
使用者的 IP 為(A),分別經過兩個Proxy 伺服器(B,C),最後到達 Web 服務器,那麼Web 服務器接收到的 X-Forwarded-For 就是 A,B。

那麼 PHP 如何擷取真實用戶端 IP 呢?

$ip = isset($_SERVER[‘HTTP_X_FORWARDED_FOR‘]) ? trim($_SERVER[‘HTTP_X_FORWARDED_FOR‘]) : ‘‘;if (!$ip) {    $ip = isset($_SERVER[‘REMOTE_ADDR‘]) ? trim($_SERVER[‘REMOTE_ADDR‘]) : ‘‘;}$a = explode(‘|‘, str_replace(‘,‘, ‘|‘, $ip));$ip = trim($a[0]);

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

配置反向 Proxy

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

現在只要是具備一定規模的網站(Web 服務器大於 1 台),為了安全和負載平衡考慮都會在 Web 服務器前面部署反向 Proxy,反向 Proxy有 HAproxy,Nginx,Apache 等等。

這裡通過 Nginx 來部署反向 Proxy:

proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;

簡單的解釋下:

  • X-Forwarded-For 表示 Nginx 接收到的頭,原樣的轉寄過來(假如不轉寄,Web 服務器就不能擷取這個頭)。
  • X-Real-IP,這是一個內部協議頭(就是反向 Proxy伺服器和 Web 服務器約定的),這個頭表示串連反向 Proxy伺服器的 IP 位址(這個地址不能偽造),其實個人覺得為了讓 PHP 代碼保持無二義性,不應該這樣設定,可以修改為 proxy_set_header REMOTE_ADDR $remote_addr;
Apache WEB 伺服器的 Access 日誌如何擷取 X-Forwarded-For 頭

其實寫這篇文章主要是因為自己在 Apache Web 服務器上擷取不到 X-Forwarded-For(上層的負載平衡裝置確定傳遞了),搜尋了下(在 Apache 官方文檔並沒有找到解決方案),解決如下:

LogFormat "%{X-Forwarded-For}i %a %h %A %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
X-Forwarded-For 安全性

那麼很多同學會說,通過 X-Forwarded-For 就能擷取到使用者的真實 IP,是不是萬事大吉了,對於 Web 服務器來說,安全有兩個緯度,第一個緯度是 REMOTE_ADDR 這個頭,這個頭不能偽造。第二個緯度就是 X-Forwarded-For,但是這個頭是可以偽造的。

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

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

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

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

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

假如提供的服務可能就是一些非機密服務,也不需要知道使用者的真實 IP,那麼建議應用程式或者 Web 服務器對 REMOTE_ADDR 做一些限制,比如進行限速等等,也可以允許存取一些白名單的代理 IP,但是這些白名單 IP 就太難衡量了。

假設你的服務很重要,比如抽獎(一個 IP 只能一次抽獎),這時候你可能想通過 X-Forwarded-For 來擷取使用者的真實 IP(假如使用 REMOTE_ADDR 則會誤殺一片),但是由於 X-Forwarded-For 可能會偽造,所以其實並沒有什麼好的辦法,只能在應用程式層進行處理了。

X-Forwarded-For的一些理解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.