淺談Nginx之反向代理

Nginx是一個異步框架的 Web服務器,也能夠用做反向代理,負載平衡器 和 HTTP緩存,今天咱們就來聊聊反向代理。html

什麼是反向代理?

反向代理(Reverse Proxy)方式是指以代理服務器來接受internet上的鏈接請求,而後將請求轉發給內部網絡上的服務器,並將從服務器上獲得的結果返回給internet上請求鏈接的客戶端,此時代理服務器對外就表現爲一個反向代理服務器。nginx

咱們換個方式理解,就是當外部網絡對內部網絡器是不能直接訪問的,要經過一個代理服務器才能進行訪問,而外部網絡看到的只是代理服務器,反饋也是由代理服務器返回的,外部網絡對於代理服務器與內部網絡直接的具體狀況是不可見的。web

正向代理和反向代理什麼區別?

正向代理是一個位於客戶端和原始服務器(origin server)之間的服務器,爲了從原始服務器取得內容,客戶端向代理髮送一個請求並指定目標(原始服務器),而後代理向原始服務器轉交請求並將得到的內容返回給客戶端。客戶端才能使用正向代理。後端

這裏有一個最顯著的區別是:(能夠看下面的圖示來感覺)緩存

  • 正向代理是客戶端知道目的服務器在哪裏,而後經過代理服務器去訪問客戶端不能直接訪問的目標服務器,而目標服務器並不知道客戶端經過什麼來訪問的, 即 正向代理代理的是客戶端
  • 反向代理中,外部網絡對於內部網絡具體的狀況是不可見的,而代理服務器來代理內部網絡來返回所要的數據(固然靜態文件能夠放在Nginx,這個靜動分離再說),而服務端知道請求的來源以及數據 反向代理代理的是服務端
    Nginx正反向代理圖示

反向代理的好處

  1. 保護了真實的web服務器,web服務器對外不可見,外網只能看到反向代理服務器,而反向代理服務器上並無真實數據,所以,保證了web服務器的資源安全。
  2. 反向代理爲基礎產生了動靜資源分離以及負載均衡的方式,減輕web服務器的負擔,加速了對網站訪問速度(動靜資源分離和負載均衡會之後說)
  3. 節約了有限的IP地址資源,企業內全部的網站共享一個在internet中註冊的IP地址,這些服務器分配私有地址,採用虛擬主機的方式對外提供服務;

反向代理在Nginx.conf的簡單配置

server {
        listen       8182;
        server_name  localhost;
        ...
        location / {
	    proxy_pass http://localhost:8082;  
	    ...
        }
        
    }
複製代碼

server塊能夠理解爲一個虛擬主機,此時咱們若是調用的是http://localhost:8182時,會將這個請求轉發到http://localhost:8082,所以實際處理這個請求的是http://localhost:8082安全

使用Nginx後web服務器如何得到真實的用戶IP

問題:

當使用Nginx後,web服務器中request.getRemoteAddr(),獲得的是Nginx的ip,而不是真實用戶的ipbash

解決方案:

在nginx.conf的的中的location中添加一些賦值操做服務器

server {
        ...
        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;
        }
        
    }
複製代碼

而後web服務端就能夠能夠經過request.getHeader("X-Forwarded-For");來得到真實的用戶ip網絡

知識點介紹:

  • proxy_set_header X-real-ip $remote_addr;
    這裏的X-real-ip是一個自定義名,名字隨意,效果是能夠將 ip 就被放在 X-real-ip 這個變量裏了,能夠經過request.getHeader("X-real-ip ")獲取當前的值,與X-Forwarded-For,下文會進行解釋
  • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

首先咱們要知道什麼是X-Forwarded-For?

X-Forwarded-For:簡稱XFF頭,它表明客戶端,也就是HTTP的請求端真實的IP,只有在經過了HTTP 代理或者負載均衡服務器時纔會添加該項。用於識別經過HTTP代理或負載平衡器原始IP一個鏈接到Web服務器的客戶機地址的非rfc標準,負載均衡

當Nginx有進行X-Forwarded-For設置的話,每次通過proxy轉發都會有記錄,格式就是client1, proxy1,proxy2,以逗號隔開各個地址,並且因爲他是非rfc標準,因此默認是沒有的,須要強制添加,經過Proxy轉達的時候,後端服務器看到的遠程ip是Proxy的ip,也就是說若是直接使用request.getHeader("X-Forwarded-For")是獲取不到用戶ip的,那咱們要如何設置得到用戶ip呢?

此時就須要在nginx配置的location塊中添加

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
複製代碼

注意這裏的意思是增長到X-Forwarded-For中,不是覆蓋,而增長後的格式就是以前說的「client1,proxy1....」,默認的時候X-Forwarded-For是空的,若是有兩個nginx,而且都配置了上面這個命令,則會在web服務器的request.getHeader("X-Forwarded-For")得到的是「用戶ip,第一個nginx的ip」,分別對應以前的格式。

proxy_add_forwarded_for包含着兩個格式,前面一部分是請求頭的X-Forwarded-For,然後面$remote_addr,也就是說是遠程用戶的ip

咱們來個圖淺顯的解釋下:

反向代理X-Forwarded_For圖解

X-real-ip與X-Forwarded-For的區別

  • X-real-ip是覆蓋,而X-Forwarded-For是後面添加

    舉個例子,請求由1.1.1.1發出,通過三層代理,第一層是2.2.2.2,第二層是3.3.3.3,而本次請求的來源IP4.4.4.4是第三層代理,

    而X-Real-IP,沒有相關標準,上面的例子,若是配置了X-Read-IP,可能會有兩種狀況

    最後一跳是正向代理,可能會保留真實客戶端IP:X-Real-IP: 1.1.1.1// 最後一跳是反向代理,好比Nginx,通常會是與之直接鏈接的客戶端IP:X-Real-IP: 3.3.3.3
    複製代碼

    而X-Forwarded-For的結果則是

    X-Forwarded-For:1.1.1.1, 2.2.2.2, 3.3.3.3
    複製代碼

    因此若是隻有一層代理,則兩個值是同樣的

參考資料

相關文章
相關標籤/搜索