反向代理與 Real-IP 和 X-Forwarded-For

2021-03-02 博文視點Broadview

開篇語:

開濤新作《億級流量網站架構核心技術》出版計劃公布以來,博文視點遭受到一波又一波讀者詢問面世時間的DDos攻擊。面對億級流量的熱情,感激之餘,我們也很慶幸——這部作品質量的確過硬,不會辜負擁躉厚望,更有開濤的高度負責和體貼周到加持,讓她絕對物超所值、長久流芳。下面,看一篇來自這位技術暖男的售前支持。

——本書策劃編輯  俠少

本文作者張開濤。為保障《億級流量網站架構核心技術》一書內容的連續性,有些需要讀者了解的內容,或者書的補充和引申內容,會通過二維碼嵌入的方式引導讀者閱讀學習。大家可以關注作者公眾號「開濤的博客」,並從菜單欄「我的新書」中查閱相關內容。

============================

本文是「4.4 接入層限流」節中的「按照IP限制並發連接數配置示例」部分需要了解的內容。

當我們訪問網際網路上的服務時,大多數時,客戶端並不是直接訪問到服務端的,而是客戶端首先請求到反向代理,反向代理再轉發到服務端實現服務訪問,通過反向代理實現路由/負載均衡等策略。這樣一來在服務端拿到的客戶端IP將是反向代理IP,而不是真實客戶端IP,因此需要一種辦法來獲取到真實客戶端IP。

如下圖所示,客戶端通過Nginx Proxy1 和 Nginx Proxy2 兩層反向代理才訪問到具體服務Nginx Backend(或如Tomcat服務)。那Nginx Backend如何才能拿到真實客戶端IP呢?

接下來我們來看看如何才能獲取到客戶端真實IP。

場景1是很簡單的場景,Nginx Proxy直接把請求往後轉發,沒有做任何處理。

Nginx Proxy

192.168.107.107 nginx.conf

location /test {

    proxy_pass http://192.168.107.112:8080;

}

192.168.107.112 nginx.conf

location /test {

    proxy_pass http://192.168.107.114:8080;

}

Nginx Proxy就是簡單的把請求往後轉發。

Nginx Backend

192.168.107.114 nginx.conf

location /test {

    default_type text/html;

    charset gbk;

    echo "$remote_addr || $http_x_forwarded_for";

}

Nginx Backend輸出客戶端IP($remote_addr)和X-Forwarded-For請求頭($http_x_forwarded_for),當訪問服務時輸出結果如下所示:

192.168.107.112 ||

$remote_addr代表客戶端IP,當前配置的輸出結果為最後一個代理伺服器的IP,並不是真實客戶端IP;

在沒有特殊配置情況下,X-Forwarded-For請求頭不會自動添加到請求頭中,即Nginx Backend的$http_x_forwarded_for輸出為空。

場景2通過添加X-Real-IP和X-Forwarded-For捕獲客戶端真實IP。

Nginx Proxy

192.168.107.107 nginx.conf

location /test {

    proxy_set_header X-Real-IP $remote_addr;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_pass http://192.168.107.112:8080;

}

192.168.107.112 nginx.conf

location /test {

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_pass http://192.168.107.114:8080;

}

Nginx Backend

192.168.107.114 nginx.conf

location /test {

    default_type text/html;

    charset gbk;

    echo "$remote_addr ||$http_x_real_ip  ||$http_x_forwarded_for";

}

當訪問服務時,輸出結果為:

192.168.107.112 || 192.168.162.16 || 192.168.162.16, 192.168.107.107

在離用戶最近的反向代理NginxProxy 1,通過「proxy_set_header X-Real-IP $remote_addr」把真實客戶端IP寫入到請求頭X-Real-IP,在NginxBackend輸出$http_x_real_ip獲取到了真實客戶端IP;而Nginx Backend的「$remote_addr」輸出為最後一個反向代理的IP;

「proxy_set_headerX-Forwarded-For $proxy_add_x_forwarded_for」的是把請求頭中的X-Forwarded-For與$remote_addr用逗號合起來,如果請求頭中沒有X-Forwarded-For則$proxy_add_x_forwarded_for為$remote_addr。

X-Forwarded-For代表了客戶端IP,反向代理如Nginx通過$proxy_add_x_forwarded_for添加此項,X-Forwarded-For的格式為X-Forwarded-For:real client ip, proxy ip 1, proxy ip N,每經過一個反向代理就在請求頭X-Forwarded-For後追加反向代理IP。

到此我們可以使用請求頭X-Real-IP和X-Forwarded-For來獲取客戶端IP及客戶端到服務端經過的反向代理IP了。這種方式還是很麻煩,$remote_addr並不是真實客戶端IP。

為了更方便的獲取真實客戶端IP,可以使用nginx http_realip_module模塊解決,在安裝nginx時通過--with-http_realip_module安裝該模塊。NginxProxy配置和場景2一樣。

Nginx Backend

192.168.107.114 nginx.conf

real_ip_header X-Forwarded-For; 

set_real_ip_from 192.168.0.0/16; 

real_ip_recursive on; 

location /test {

    default_type text/html;

    charset gbk;

    echo "$remote_addr || $http_x_real_ip  ||$http_x_forwarded_for";

}

當訪問服務時,輸出結果為:

192.168.162.16 || 192.168.162.16 || 192.168.162.16, 192.168.107.107

X-Real-IP和X-Forwarded-For和場景2一樣;

使用realip模塊後,$remote_addr輸出結果為真實客戶端IP,可以使用$realip_remote_addr獲取最後一個反向代理的IP;

real_ip_headerX-Forwarded-For:告知Nginx真實客戶端IP從哪個請求頭獲取,如X-Forwarded-For;

set_real_ip_from192.168.0.0/16:告知Nginx哪些是反向代理IP,即排除後剩下的就是真實客戶端IP,支持配置具體IP位址、CIDR地址;

real_ip_recursive on:是否遞歸解析,當real_ip_recursive配置為off時,Nginx會把real_ip_header指定的請求頭中的最後一個IP作為真實客戶端IP;當real_ip_recursive配置為on時,Nginx會遞歸解析real_ip_header指定的請求頭,最後一個不匹配set_real_ip_from的IP作為真實客戶端IP。

如果配置「real_ip_recursive off; 」,則輸出結果為:

192.168.107.107 || 192.168.162.16 ||192.168.162.16, 192.168.107.107

通過「proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for」 把從真實客戶端IP和反向代理IP通過逗號分隔,添加到請求頭中;

可以在第一個反向代理上配置「proxy_set_header X-Real-IP $remote_addr」 獲取真實客戶端IP;

配合realip模塊從X-Forwarded-For也可以獲取到真實客戶端IP。

在整個反向代理鏈條的第一個反向代理可以不配置「proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for」,否則客戶端可以偽造X-Forwarded-For從而偽造客戶端真實IP,如果服務端使用X-Forwarded-For第一個IP作為真實客戶端IP,則就出問題了。如果通過配置X-Real-IP請求頭或者配合realip模塊也不會出現該問題。如果自己解析X-Forwarded-For的話,記得使用realip算法解析,而不是取第一個。

當我們進行限流時一定注意限制的是真實客戶端IP,而不是反向代理IP,我遇到過很多同事在這塊出問題的。


喜歡請分享至朋友圈

了解更多圖書詳情請點擊閱讀原文

長按二維碼輕鬆關注

相關焦點

  • Spring Cloud學習筆記——Nginx和Zuul以及正向代理和反向代理
    Spring Cloud學習筆記——Nginx和Zuul正向代理和反向代理對於Java程式設計師來說,提供代理,可以第一時間想到的是Java中的代理模式,靜態代理、動態代理或Cglib等。但是,我們今天聊的代理,是位於網絡訪問請求過程的代理。
  • WEB裡面的反向代理是什麼意思
    不同於前進代理,前進代理將從網際網路上獲得的資源以媒介的形式返回給相關的客戶端,而前進代理則是作為代理在伺服器端(例如 Web伺服器)使用的,而非客戶端。客戶機可以通過前向代理訪問許多不同的資源,反向代理就是許多客戶機在不了解後端伺服器存在的情況下通過它訪問不同後端伺服器上的資源,認為所有的資源都來自這個後端伺服器。
  • IP代理和ADSL撥號獲取IP位址的方式有哪些不同?
    網絡的快速發展和技術的飛速進步讓我們每個人每天都在和網絡打交道,而實現網絡的互聯則少不了IP位址功勞,它就是網絡的通行證任何聯網設備中如果沒有分配到對應的IP位址則無法實現網絡的連接,在這其中IP獲取的方式通常分為IP代理和ADSL撥號兩種,那它們有何不同呢?
  • 靜態IP代理的用途
    相信很多經常上網的小夥伴對於IP位址並不陌生,對於網絡工作者來講換ip地址是需要經常遇到的,通常我們可以重啟路由或者使用代理ip伺服器來解決。今天就給大家科普一下代理IP本身的用途以及優勢。主要以靜態代理IP為例,靜態IP又稱固定IP位址,是一種長期分配給一臺計算機或網絡設備使用的 IP 地址。由於靜態IP的特性是重新撥號上網後得到的IP一直是固定不變的,因此它主要用於企業用途,優點最主要就是:IP固定後便於企業信息化系統的管理、穩定性更高。
  • 八爪魚添加番茄IP代理的方法
    爬蟲數據對於爬蟲來說,為了解決封禁 IP 的問題,一個有效的方式就是使用代理,使用代理之後可以讓爬蟲偽裝自己的真實 IP,如果使用大量的隨機的代理進行爬取,那麼網站就不知道是我們的爬蟲一直在爬取了那怎麼使用代理IP設置爬蟲軟體呢?今天舉例:用番茄IP來設置國內抓取數據工具-八爪魚。首先,登陸登陸八爪魚軟體,進入軟體操作界面。
  • 網頁與遊戲中封鎖限制IP如何通過IP代理來解決
    伴隨著網際網路的迅速發展趨勢,許多與網際網路有關的工作中都必須線上開展,如網絡爬蟲,推廣營銷,投票點讚,補單刷流量,等工作中時必須經常實際操作同一網頁頁面時非常容易開啟該網頁伺服器限定,造成IP封號,造成沒法一切正常打開網站,而玩家在打遊戲或遊戲多開手機遊戲時,全是同一IP位址登陸,也會造成伺服器禁封IP,進而造成沒法一切正常手機遊戲,這種限定都是有一個相同點,全是限定大家的IP,進而造成我們無法一切正常網頁瀏覽和打遊戲
  • 爬蟲必備—快速搭建國際梯子,動態IP池
    測試$ curl http://httpbin.org/ip$ torsocks curl http://httpbin.org/ip以上兩個命令分別是獲取本機真實IP,和Tor代理訪問後的IP。不出意外,可以看到兩個結果是不同的PrivoxyTor提供的是SOCKS5代理, 但爬蟲程序通常用的是http代理,需要有個工具將http請求轉發到SOCKS代理,使用Privoxy可以解決該問題。
  • 網絡大數據時代IP代理起到了哪些作用?
    在如今這個網絡大數據時代,與網際網路相關的行業是越來越多,而網站安全、排名及訪問量和IP相關問題,備受這些從業者的關注,特別是其中IP位址相關問題,是普通網民和網絡工作者共同在意的問題,例如IP被封IP限制問題就會導致工作停滯和網絡的正常使用,針對這些狀況IP代理就能很好的解決,具有修改更換隱藏ip屬性,達到突破各類限制從而保護網絡安全的目的
  • 應用聯發科天璣1000+處理器,realme X7 Pro與realme 7 5G手機登臺
    realme今(22)日舉辦「4舍5入- Log in 5G」記者會,發表兩款5G新機realme X7 Pro以及realme 7 5G,這兩款機種分別採用聯發科天璣1000+以及天璣800U處理 器,搭配閃充、高螢幕更新率等特性,期待帶領消費者一起從4G跨入5G!
  • realme X 朋克藍、蒸汽白兩種配色真機實拍照曝光
    realme X 朋克藍、蒸汽白兩種配色真機實拍照曝光 站長之家(ChinaZ.com) 5 月 14 日消息:昨天上午,realme 手機官方宣布將於 5 月
  • realme X2 Pro正式發布:2699元起,真香!
    10月15日上午,realme手機舉辦新品發布會,正式推出realme
  • 代理IP獨享和共享的區別
    伴隨著代理IP的快速發展,市面上的代理商們依據不同的客戶需求推出了各種各樣的代理方案。有靜態的,動態的,高匿的等等,其中最受關注的還是「獨享IP」。與獨享IP相對應的是共享IP,從字面上理解,獨享即獨自使用一個IP,共享IP即多個人同時共同使用一個IP。那在使用時它們有什麼區別呢?
  • 在歐洲發布的realme 7,或為 realme V5國際版
    據外媒透露,realme7 5G 在今年11月12日通過了 NBTC 認證,隨後, realme 官方就在 Twitter 上確認了 realme 7 5G 的發布日期,為 11 月 19 日。雖然該機其他信息在發布前未被曝出,但是有猜測稱realme 7 5G 很可能是此前在國內推出的 realme V5 更名上市。
  • 代理伺服器有哪幾種 如何獲取代理伺服器【詳細介紹】
    如果需要,您要向您的網絡管理員申請一個用戶和口令。  知道了上述信息,您就可以把這些信息填入「網絡配置」中,或者在第一次登記時填入,您就可以使用socks代理了。  在實際應用中SOCKS代理可以用作為:電子郵件、新聞組軟體、網絡傳呼ICQ、網絡聊天MIRC和使用代理伺服器上聯眾打遊戲等等各種 遊戲 應用軟體當中。
  • 手遊多開怎麼切換不同IP防封號,手遊多開切換單窗口IP方法介紹
    現在很多手遊公司都是通過IP檢測來判斷一個號是玩家號還是工作室帳號,如果有多帳號在同一個ip下就會被判定為手遊工作室的帳號,很多喜歡多開養號的小夥伴們因此不幸中招,導致多開搬磚也被誤封帳號。 做推廣運營、刷單刷量的小夥伴也是一樣,明明都是私人的號卻被誤封。如果不更換ip,很容易就出現帳號被封,ip地址被封的情況。咱們怎麼樣才能自由更換ip,實現ip自由呢?
  • 安卓手機/蘋果手機怎麼無限自動切換IP
    不過流量卡的ip也就那麼一些,跳來跳去很多人用,導致ip重複,會引起封號的,但是現在還有很多人再用流量卡,流量卡也慢慢改進了,但是這種還不是最穩的。2.硬改由器,俗稱硬---改!這種的一般適合工作室網線比較多的,例如一次性有三十根或者五十根之類的,這種路由器可以改mac的!這種路由器用的多一些,不過現在用的也很少了。
  • real主演金秀賢為什麼哭了?電影real試映會上發生了什麼事情?
    由金秀賢和崔雪莉主演的韓國電影《real》近日在首爾舉行了媒體試映會,試映會上男一號金秀賢突然哽咽落淚,臺下觀眾紛紛為他加油打氣。「星星男神」為什麼哭了?據悉,此次電影《real》拍攝過程十分艱苦,拍了幾乎半年時間。而金秀賢在片中飾演患有多重人格的男主張泰英,並首次挑戰了一人分飾兩角。
  • Realme宣布在印度舉行發布會
    該發布計劃用於Realme Buds Air Pro Master Edition真正的無線耳機和Realme Watch S Pro智能手錶。 realme傾向於發布其產品的Master版本。雖然realme X Master Edition僅限於諸如realme X2 Pro Master Edition和realme X50 5G Master Edition之類的手機,但對於realme Buds Air Pro Master Master Edition可能並沒有說相同的話。 此版本與標準版本之間的主要區別是顏色。
  • 用路由器如何查找ip和mac地址?有兩種辦法
    路由器是目前大家使用較多的工具,也是手機使用wifi網絡不可或缺的工具,由於路由器屬於信息傳送和收發的中心點,因此自己的網絡被人使用的話,你的隱私很容易被別人獲取,一般來說,如果電腦或者手機設備連接了該路由器,可以在路由器的後臺或者使用MAC地址掃描工具兩種辦法查看到所連接的設備的ip地址和Mac
  • 放棄蘋果,從realmeX2Pro開始
    相信很多小夥伴都發現,近年來飛速發展智慧型手機不僅性能更好、像素更高,而且屏幕也越來越大,特別是全屏普及之後,大屏幕和手感都可以實現,這讓廣大消費者非常高興。不過,隨著廣大消費者對屏幕的需求不斷增加,除了屏幕的亮度、色彩和比例外,屏幕刷新率也成為屏幕的又一突破。