1. 程式人生 > 實用技巧 >十三、nginx的反向代理

十三、nginx的反向代理

一、反向代理的概念

反向代理是nginx的一個重要功能,在編譯安裝時會預設編譯該模組。在配置檔案中主要配置 proxy_pass指令。

代理伺服器接受客戶端的請求,然後把請求代理給後端真實伺服器進行處理,然後再將伺服器的響應結 果返給客戶端。

反向代理:reverse proxy,可代理外網使用者的請求到內部的指定web伺服器,並將資料返回給使用者
nginx除了可以在企業提供高效能的web服務之外,另外還可以將本身不具備的請求通過某種預定義的協議轉發至其它伺服器處理,不同的協議就是nginx伺服器與其他伺服器進行通訊的一種規範
主要在不同的場景使用以下模組實現不同的功能:
ngx_http_proxy_module: 將客戶端請求以http協議轉發至後端伺服器
ngx_http_fastcgi_module:將客戶端對php請求以fastcgi協議轉發至後端
ngx_http_uwsgi_module:將客戶端對Python請求以uwsgi協議轉發至後端
ngx_stream_proxy_module:將客戶端請求以tcp協議轉發至後端伺服器

二、nginx反向代理作用

與正向代理(正向代理主要是代理客戶端的請求)相反,反向代理主要是代理伺服器返回的資料,所以 它的作用主要有以下兩點:

  1. 可以防止內部伺服器被惡意攻擊(內部伺服器對客戶端不可見)。

  2. 為負載均衡和動靜分離提供技術支援。

三、反向代理語法

Syntax: proxy_pass URL;
Default: —
Context: location, if in location, limit_except

代理伺服器的協議,可支援http與https。

地址可以指定為域名或IP地址,以及可選埠。

proxy_pass http://localhost:9000/uri/;
proxy_pass http://192.168.0.188:8080; proxy_pass http://192.168.0.188;

四、方向代理案例

案例1:

location和proxy_pass都不帶uri路徑。

代理伺服器:192.168.0.109

後端伺服器:192.168.0.114

代理伺服器的簡單配置:
location / {
   proxy_pass http://192.168.0.114;
}
# proxy_pass 轉發請求給後端伺服器

後端伺服器的配置:

location / {  
echo $host;
root html;
index index.html index.htm;
}
# echo
$host 這個主要是來看下後端接收到的Host是什麼。

測試:

[root@localhost ~]# curl 192.168.0.109
192.168.0.114
# 獲取的請求Host是後端伺服器ip,去掉該指令,驗證請求結果。
[root@localhost ~]# curl 192.168.0.109
this is 114 page
# 可以看到我們訪問的是109,但是得到的結果是114的釋出目錄檔案。

案例2:

proxy_pass沒有設定uri路徑,但是代理伺服器的location 有uri,那麼代理伺服器將把客戶端請求的 地址傳遞給後端伺服器。

代理伺服器的配置:

location /document/data/ {
    proxy_pass http://192.168.0.114;
}

後端伺服器的配置:

location / {
    # echo $host;
    root html/uri;
    index index.html index.htm;
}

測試:

[root@localhost ~]# mkdir -p /usr/local/nginx/html/uri/document/data/
[root@localhost ~]# echo "this is /usr/local/nginx/html/uri/document/data/ test"
> /usr/local/nginx/html/uri/document/data/index.html
> 
[root@localhost ~]# curl 192.168.0.109/document/data/
this is /usr/local/nginx/html/uri/document/data/ test 
# 完整請求路徑 是在後端伺服器的/usr/local/nginx/html/uri 後追加客戶端請求的路徑/document/data/

案例3:

如果proxy_pass設定了uri路徑,則需要注意,此時,proxy_pass指令所指定的uri會覆蓋location的 uri。

代理伺服器的配置:

location / {
proxy_pass http://192.168.0.114/data/;
}

後端伺服器的配置:

location / {
root html;
index index.html index.htm;
}

測試:

[root@localhost ~]# mkdir -p /usr/local/nginx/html/data/
[root@localhost ~]# echo "this is /usr/local/nginx/html/data test。" >
/usr/local/nginx/html/data/index.html
[root@localhost ~]# curl 192.168.0.109
this is /usr/local/nginx/html/data test

這樣看好像很正常,但是稍作修改。

這次加上location的uri,後端伺服器加個子目錄:

代理伺服器的配置:

location /document/ {
proxy_pass http://192.168.0.114/data/;
}

後端伺服器的配置:

location / {
#echo $host;
root html;
index index.html index.htm;
}

測試:

[root@localhost ~]# curl 192.168.0.109/document/
this is /usr/local/nginx/html/data test。
# 該路徑還是 proxy_pass 指定的uri路徑,與location 沒有關係了!

五、獲取遠端客戶端真實ip地址:

代理伺服器配置:

location / {
proxy_pass http://192.168.0.114;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

後端伺服器配置

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_real_ip"';
access_log logs/access.log main;

可以獲取真是的訪問ip,而非代理地址。