Nginx是一個異步框架的 Web服務器,也能夠用做反向代理,負載平衡器 和 HTTP緩存,今天咱們就來聊聊反向代理。html
反向代理(Reverse Proxy)方式是指以代理服務器來接受internet上的鏈接請求,而後將請求轉發給內部網絡上的服務器,並將從服務器上獲得的結果返回給internet上請求鏈接的客戶端,此時代理服務器對外就表現爲一個反向代理服務器。nginx
咱們換個方式理解,就是當外部網絡對內部網絡器是不能直接訪問的,要經過一個代理服務器才能進行訪問,而外部網絡看到的只是代理服務器,反饋也是由代理服務器返回的,外部網絡對於代理服務器與內部網絡直接的具體狀況是不可見的。web
正向代理是一個位於客戶端和原始服務器(origin server)之間的服務器,爲了從原始服務器取得內容,客戶端向代理髮送一個請求並指定目標(原始服務器),而後代理向原始服務器轉交請求並將得到的內容返回給客戶端。客戶端才能使用正向代理。後端
這裏有一個最顯著的區別是:(能夠看下面的圖示來感覺)緩存
server {
listen 8182;
server_name localhost;
...
location / {
proxy_pass http://localhost:8082;
...
}
}
複製代碼
server塊能夠理解爲一個虛擬主機,此時咱們若是調用的是http://localhost:8182時,會將這個請求轉發到http://localhost:8082,所以實際處理這個請求的是http://localhost:8082安全
當使用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網絡
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-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
複製代碼
因此若是隻有一層代理,則兩個值是同樣的