文章目錄
在講反向代理之前,我們再次回顧一下什麼是代理服務器和正向代理。
一、代理服務器
代理服務器,客戶機在發送請求時,不會直接發送給目的主機,而是先發送給代理服務器,代理服務器接受客戶機請求之後,再向主機發出,並接收目的主機返回的數據,存放在代理服務器的硬盤中,再發送給客戶機。
舉個例子: 代理 就如同生活中的專賣店~客人到adidas專賣店買了一雙鞋,這個專賣店就是代理,被代理角色就是adidas廠家,目標角色就是用戶。
1.1 爲什麼要使用代理服務器?
(1)提高訪問速度:
由於目標主機返回的數據會存放在代理服務器的硬盤中,因此下一次客戶再訪問相同的站點數據時,會直接從代理服務器的硬盤中讀取,起到了緩存的作用,尤其對於熱門站點能明顯提高請求速度。
(2)防火牆作用:
由於所有的客戶機請求都必須通過代理服務器訪問遠程站點,因此可在代理服務器上設限,過濾某些不安全信息。
(3)通過代理服務器訪問不能訪問的的目標站點:
互聯網上有許多開發的代理服務器,客戶機在訪問受限時,可通過不受限的代理服務器訪問目標站點。
1.2 什麼是正向代理?
一個位於客戶端和原始服務器(origin server)之間的服務器,爲了從原始服務器取得內容,客戶端向代理髮送一個請求並指定目標(原始服務器),然後代理向原始服務器轉交請求並將獲得的內容返回給客戶端。客戶端才能使用正向代理。
正向代理總結就一句話:代理端代理的是客戶端。
正向代理最大的特點就:客戶端非常明確要訪問的服務器地址;服務器只清楚請求來自哪個代理服務器,而不清楚來自哪個具體的客戶端。;正向代理模式屏蔽或者隱藏了真實客戶端信息。
1.3 什麼是反向代理?
反向代理(Reverse Proxy)方式是指以代理服務器來接受internet上的連接請求,然後將請求,發給內部網絡上的服務器並將從服務器上得到的結果返回給internet上請求連接的客戶端,此時代理服務器對外就表現爲一個反向代理服務器。
反向代理總結就一句話:代理端代理的是服務端。
舉個例子:幾乎所有人都用過淘寶,每天同時連接到淘寶網站的訪問人數已經爆表,單個服務器遠遠不能滿足人民日益增長的購買慾望了,此時就出現了一個大家耳熟能詳的名詞:分佈式部署;也就是通過部署多臺服務器來解決訪問人數限制的問題;淘寶網站中大部分功能也是直接使用nginx進行反向代理實現的,並且通過封裝nginx和其他的組件之後起了個高大上的名字:Tengine
上圖表示的是全國各地的用戶在淘寶客戶端發出請求,經過了Nginx 反向代理服務器,nginx服務器接收到之後,按照一定的規則分發給了後端的業務處理服務器進行處理。
特點:此時請求的來源客戶端是明確的,但是請求具體由哪臺服務器處理的並不明確了。
反向代理,主要用於服務器集羣分佈式部署的情況下,反向代理隱藏了服務器的信息
二、Nginx反向代理獲取客戶端的真實IP
我們訪問互聯網的服務時,大多數時,客戶端並不是直接訪問到服務端的,而是客戶端首先請求到反向代理,反向代理再轉發到服務端實現服務訪問。
可以看出,nginx的反向代理實現跨域的同時也徹底改變了服務器的請求來源,隔離了用戶和服務器的連接,服務端獲取不到真實的客戶端ip,只能獲取到反向代理服務的ip,那麼nginx怎樣才能獲取到真實的ip呢?
- 利用Nginx中的realip模塊獲取用戶的真實ip。將各層代理的IP排除在外,就取到了真實的用戶IP,這個可以使用nginx的一個模塊realip_module 來實現從XFF中拋棄指定的代理層 IP,得到一個符合規則的就是用戶IP 。nginx的 realip_module 模塊需要在編譯nginx的時候加上參數–with-http_realip_module。
2.1 用一臺服務器模擬實現獲取本機ip
1、進入解壓目錄,添加realip_module模塊,重新編譯,make
./configure --prefix=/usr/local/nginx --with-file-aio --with-http_realip_module
nginx -V
,查看編譯參數
2、添加虛擬主機: vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name server1;
location / {
return 200;
}
}
3、開啓nginx服務且測試:200 ok說明虛擬主機添加成功 (添加本機解析)
4、檢測成功時,我們讓他 迴應real ip
- ==$remote_addr:代表客戶端的IP,但它的值不是由客戶端提供的,而是服務端根據客戶端的ip指定的,並不是真實客戶端IP; ==. 當你的瀏覽器訪問某個網站時,假設中間沒有任何代理,那麼網站的web服務器(Nginx,Apache等)就會把remote_addr設爲你的機器IP,如果你用了某個代理,那麼你的瀏覽器會先訪問這個代理,然後再由這個代理轉發到網站,這樣web服務器就會把remote_addr設爲這臺代理機器的IP,,除非代理將你的IP附在請求header中一起轉交給web服務器
server {
listen 80;
server_name server1;
location / {
return 200 "client real ip: $remote_addr\n";
}
}
5、平滑重啓nginx,再次測試:
6、 從X-Forwarded-For中獲取到真實客戶端IP ,更改配置文件:vim /usr/local/nginx/conf/nginx.conf
- X-Forwarded-For: 簡稱XFF頭,它代表客戶端,也就是HTTP的請求端真實的IP,只有在通過HTTP 代理或者負載均衡服務器時纔會添加該項,正如上面所述,當你使用了代理時,web服務器就不知道你的真實IP了,爲了避免這個情況,代理服務器通常會增加一個叫做x_forwarded_for的頭信息,把連接它的客戶端IP(即你的上網機器IP)加到這個頭信息裏,這樣就能保證網站的web服務器能獲取到真實IP。
- XFF的格式爲X-Forwarded-For: client, proxy1, proxy2。 XFF 的內容由「英文逗號 + 空格」隔開的多個部分組成,最開始的是離服務端最遠的設備 IP,然後是每一級代理設備的 IP(注意:如果未經嚴格處理,可以被僞造)。如果一個 HTTP 請求到達服務器之前,經過了三個代理 Proxy1、Proxy2、Proxy3,IP 分別爲 IP1、IP2、IP3,用戶真實 IP 爲 IP0,那麼按照 XFF 標準,服務端最終會收到以下信息X-Forwarded-For: IP0, IP1, IP2,Proxy3 直連服務器,它會給 XFF 追加 IP2,表示它是在幫 Proxy2 轉發請求,列表中並沒有 IP3,IP3 可以在服務端通過 Remote Address 字段獲得。
server {
listen 80;
server_name server1; # 添加域名
set_real_ip_from 172.25.2.1; # 真實服務器上一級代理的IP地址或者IP段,可以寫多行
real_ip_header X-Forwarded-For; # 告知Nginx真實客戶端IP從哪個請求頭獲取
real_ip_recursive off; # 是否遞歸解析,off表示默認從最後一個地址開始解析;on表示從前往後依次遞歸獲取ip
location / {
return 200 "client real ip: $remote_addr\n";
}
}
7、平滑重啓nginx,再次測試:curl -H “X-Forwarded-For:1.1.1.1,172.25.2.1” server1
當配置文件裏的參數 real_ip_recursive 爲off 時:
- real_ip_recursive :是否遞歸解析,off表示默認從最後一個地址開始解析;on表示從前往後依次遞歸獲取ip
配置文件裏的參數 real_ip_recursive 爲on 時:
2.2 配置真正的反向代理服務器
實驗環境
主機信息 | 主機的功能(服務) |
---|---|
server1(172.25.2.1) | 後端服務器 (nginx+http_realip_module ) |
server2(172.25.2.2) | 反向代理服務器 |
真機(172.25.2.250) | 用作客戶端測試 |
1、在server1上面進行配置,修改nginx服務器默認發佈頁面的內容
2、修改配置文件,添加內容
3、進行語法檢測,重啓服務
4、將server1上編譯好的nginx的目錄發送給server2
5、在server2(代理服務器)上面進行配置,代理服務器的配置參考官網
6、編寫server2代理服務器上的配置文件
7、刪除代理服務器server2上面的web資源
8、在真機上面進行測試,寫解析
9、可以看到訪問的域名對應的是server2主機的IP,但是訪問到的內容卻是server1的發佈頁
在server1上查看訪問日誌:/usr/local/nginx/logs/access.log
可以看到nginx服務器可以直接獲取到客戶端的ip。
註釋掉nginx服務器的這兩行時,獲取到的ip就是代理服務器的ip
在server1上查看訪問日誌:/usr/local/nginx/logs/access.log
可以看到nginx服務器獲取的ip爲代理服務器的ip。