Nginx反向代理中使用proxy_redirect重定向url


 

在使用Nginx做反向代理功能時,有時會出現重定向的url不是我們想要的url,這時候就可以使用proxy_redirect進行url重定向設置了。proxy_redirect功能比較強大,其作用是對發送給客戶端的URL進行修改!!
語法:proxy_redirect [ default|off|redirect replacement ];
默認:proxy_redirect default;
配置塊(使用的字段):http、server、location
當上游服務器返回的響應是重定向或刷新請求(如HTTP響應碼是301或者302)時,proxy_redirect可以重設HTTP頭部的location或refresh字段。

        location /login {
            proxy_pass http://target_servers/login ;
        }

如果需要修改從被代理服務器傳來的應答頭中的"Location"和"Refresh"字段,這時候就可以用proxy_redirect這個指令設置。

假設被代理服務器返回Location字段為http://localhost:8000/kevin/some/uri/
 
proxy_redirect http://localhost:8000/kevin/ http://frontend/one/;
將Location字段重寫為http://frontend/one/some/uri/。
在代替的字段中可以不寫服務器名:

proxy_redirect http://localhost:8000/kevin/ /;
這樣就使用服務器的基本名稱和端口,即使它來自非80端口。
如果使用"default"參數,將根據location和proxy_pass參數的設置來決定。


例如下列兩個配置等效:
location /one/ {  
proxy_pass       http://upstream:port/kevin/;  
proxy_redirect   default;
} 

location /one/ {  
proxy_pass       http://upstream:port/kevin/;  
proxy_redirect   http://upstream:port/kevin/   /one/;
}

在指令中可以使用一些變量:
proxy_redirect   http://localhost:8000/    http://$host:$server_port/;

這個指令有時可以重復:
proxy_redirect   default;  
proxy_redirect   http://localhost:8000/    /;  
proxy_redirect   ;  
/;

參數off將在這個字段中禁止所有的proxy_redirect指令:
proxy_redirect   off;  

利用這個指令可以為被代理服務器發出的相對重定向增加主機名:

下面通過幾個小實例來體驗下proxy_redirect的使用效果:
==============================================================================

假設當前nginx的訪問地址為http://10.0.9:8080,如果kevin-inc又需要302到10.0.9/xxx
那么可以添加下redirect,將302的location改為http://10.0.9:8080/xxx

location /login {
            proxy_pass http://kevin-inc/login ;
            proxy_redirect http://10.0.9/ http://10.0.9:8080/;
        }

--------------------------------
host變量
如果不想寫死ip地址,可以使用nginx的變量

location /login {
            proxy_pass http://kevin-inc/login ;
            proxy_redirect http://$host/ http://$http_host/;
        }

其中host不帶端口的,也就是nginx部署的主機ip,而$http_host是帶端口的

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

server { 
       listen       80; 
       server_name  www.kevin.com; 
       location / { 
            proxy_pass http://10.0.8.40:9080; 
       } 
   }

這段配置一般情況下都正常,但偶爾會出錯, 抓包發現服務器給客戶端的跳轉指令里加了端口號,如Location: http://www.kevin.com:9080/abc.html 。
因為nginx服務器偵聽的是80端口,所以這樣的URL給了客戶端,必然會出錯.
針對這種情況, 加一條proxy_redirect指令: proxy_redirect http://www.kevin.com:9080/ / ,即把所有"http://www.kevin.com:9080/"的內容替換成
"/"再發給客戶端,就解決了。 

server { 
       listen       80; 
       server_name  www.kevin.com; 
       proxy_redirect http://www.kevin.com:9080/ /; 
       location / { 
            proxy_pass http://10.0.8.40:9080; 
       } 
   } 

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

前端的Nginx負責把http://www.kevin.com/grace/Server/開頭的url反向代理到后端的http://10.0.8.40/Server/上。
對於有完整的路徑,如http://www.kevin.com/grace/Server/的代理沒有問題,Server對應后台服務器的一個目錄。

但當訪問http://www.kevin.com/grace/Server時,后端Nginx會發送一個301到/上,於是返回到前端后URL變成了http://www.kevin.com/Server/,這個url顯然不是我們想要的。

在Apache中有個ProxyPassReverse的參數,用來調整反向代理服務器發送的http應答頭的url,可以解決這個問題。
在Nginx代理配置,可以使用proxy_redirect這個參數,它實現的功能和ProxyPassReverse類似,例如增加如下配置:

location ^~ /grace  {  
    proxy_pass http://10.0.8.40/;  
    proxy_redirect http://www.kevin.com/ /grace/;  
}  

==============================================================================
如下啟用了proxy_redirect配置(http->https),配置中就不需要"proxy_set_header Host $host;",即不需要"添加發往后端服務器的請求頭"的配置了

[root@external-lb01 vhosts]# cat 80-www.kevin.com.conf
server {
        listen       80;
        server_name  www.kevin.com kevin.com;

        access_log  /data/nginx/logs/www.kevin.com-access.log main;
        error_log  /data/nginx/logs/www.kevin.com-error.log;

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        return      301 https://$server_name$request_uri;
}



[root@external-lb01 ~]# cat /data/nginx/conf/vhosts/443-www.kevin.com.conf.bak
upstream scf_cluster {
    ip_hash;
    server 192.168.10.20:9020;
    server 192.168.10.21:9020;
    }
upstream portal_cluster {
    ip_hash;
    server 192.168.10.20:9040;
    server 192.168.10.21:9040;
    }
upstream file_cluster{
    ip_hash;
    server 192.168.10.20:9020;
    }
upstream workflow_cluster{
    ip_hash;
    server 192.168.10.20:9020;
    server 192.168.10.21:9020;
    }
upstream batch_cluster{
    server 192.168.10.20:9020;
    server 192.168.10.21:9020;
    }
  
server {
        listen       443;
        server_name  www.kevin.com kevin.com;
  
        ssl on;
        ssl_certificate /data/nginx/conf/ssl/kevin.cer;
        ssl_certificate_key /data/nginx/conf/ssl/kevin.key;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers  ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;
        ssl_prefer_server_ciphers  on;
  
        access_log  /data/nginx/logs/www.kevin.com-access.log main;
        error_log  /data/nginx/logs/www.kevin.com-error.log;
  
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
  
  
        location /scf {
            proxy_pass http://scf_cluster/scf;
            proxy_redirect  http://scf_cluster/scf https://www.kevin.com/scf;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_connect_timeout 300;
            proxy_send_timeout 300;
            proxy_read_timeout 600;
            proxy_buffer_size 256k;
            proxy_buffers 4 256k;
            proxy_busy_buffers_size 256k;
            proxy_temp_file_write_size 256k;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
            proxy_max_temp_file_size 128m;
  
        }
  
  
       location / {
            proxy_pass http://portal_cluster/portal-pc/;
            proxy_redirect  http://portal_cluster/portal-pc/ https://www.kevin.com/;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_connect_timeout 300;
            proxy_send_timeout 300;
            proxy_read_timeout 600;
            proxy_buffer_size 256k;
            proxy_buffers 4 256k;
            proxy_busy_buffers_size 256k;
            proxy_temp_file_write_size 256k;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
            proxy_max_temp_file_size 128m;
  
        }
  
        location /msdp-file {
            proxy_pass http://file_cluster/msdp-file;
            proxy_redirect  http://file_cluster/msdp-file https://www.kevin.com/msdp-file;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_connect_timeout 300;
            proxy_send_timeout 300;
            proxy_read_timeout 600;
            proxy_buffer_size 256k;
            proxy_buffers 4 256k;
            proxy_busy_buffers_size 256k;
            proxy_temp_file_write_size 256k;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
            proxy_max_temp_file_size 128m;
  
        }
          
    location /upload {
            proxy_pass http://file_cluster/upload;
            proxy_redirect  http://file_cluster/upload https://www.kevin.com/upload;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_connect_timeout 300;
            proxy_send_timeout 300;
            proxy_read_timeout 600;
            proxy_buffer_size 256k;
            proxy_buffers 4 256k;
            proxy_busy_buffers_size 256k;
            proxy_temp_file_write_size 256k;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
            proxy_max_temp_file_size 128m;
  
        }
          
        location /activiti-workflow-console {
            proxy_pass http://workflow_cluster/activiti-workflow-console;
            proxy_redirect  http://workflow_cluster/activiti-workflow-console https://www.kevin.com/activiti-workflow-console;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_connect_timeout 300;
            proxy_send_timeout 300;
            proxy_read_timeout 600;
            proxy_buffer_size 256k;
            proxy_buffers 4 256k;
            proxy_busy_buffers_size 256k;
            proxy_temp_file_write_size 256k;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
            proxy_max_temp_file_size 128m;
  
        }
    location /batch-framework-web {
            proxy_pass http://batch_cluster/batch-framework-web;
            proxy_redirect  http://batch_cluster/batch-framework-web https://www.kevin.com/batch-framework-web;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_connect_timeout 300;
            proxy_send_timeout 300;
            proxy_read_timeout 600;
            proxy_buffer_size 256k;
            proxy_buffers 4 256k;
            proxy_busy_buffers_size 256k;
            proxy_temp_file_write_size 256k;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
            proxy_max_temp_file_size 128m;
  
        }
}

===============================================================================
在看下nginx中非80端口的轉發,注意:當端口是非80時,proxy_set_header項的$host后面一定要加上端口

如下,當http通過proxy_pass到非80端口的做法:
[root@external-lb01 vhosts]# cat mobi.kevin.com.conf 
upstream mobi_cluster{
    server 10.0.54.20:8080;
    }

server {
        listen       80;
        server_name  mobi.kevin.com;

      access_log  /data/nginx/logs/mobi.kevin.com-access.log main;
      error_log  /data/nginx/logs/mobi.kevin.com-error.log;

    location / {
            proxy_pass http://mobi_cluster;
            proxy_set_header Host $host;
            proxy_redirect  http://mobi_cluster/ http://mobi.kevin.com/;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        } 
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        } 
}

=========================================================================
再看一個匹配上下文的代理配置

[root@uatinner-lb01 vhosts]# cat /opt/uatbob-vfc.kevin.com.conf 
server {
      listen      443;
      server_name uatbob-vfc.kevin.com;

      ssl on;
      ssl_certificate /data/nginx/conf/ssl/ssl.kevin.com.crt;
      ssl_certificate_key /data/nginx/conf/ssl/ssl.kevin.com.key;
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      ssl_session_cache    shared:SSL:1m;
      ssl_session_timeout  5m;
      ssl_ciphers  ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;
      ssl_prefer_server_ciphers  on;
    
      access_log  /data/nginx/logs/uatbob-vfc.kevin.com-access.log main;
      error_log  /data/nginx/logs/uatbob-vfc.kevin.com-error.log;
    
 location /devxcd/ {
         proxy_pass http://172.16.50.16:50002/;
         proxy_redirect off ;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header REMOTE-HOST $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_connect_timeout 300;
         proxy_send_timeout 300;
         proxy_read_timeout 600;
         proxy_buffer_size 256k;
         proxy_buffers 4 256k;
         proxy_busy_buffers_size 256k;
         proxy_temp_file_write_size 256k;
         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
         proxy_max_temp_file_size 128m;
         #proxy_cache mycache;                                
         #proxy_cache_valid 200 302 1h; 
         #proxy_cache_valid 301 1d;
         #proxy_cache_valid any 1m;
        }

 location /fvtxcd/ {
         proxy_pass http://172.16.50.75:50002/;
         proxy_redirect off ;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header REMOTE-HOST $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_connect_timeout 300;
         proxy_send_timeout 300;
         proxy_read_timeout 600;
         proxy_buffer_size 256k;
         proxy_buffers 4 256k;
         proxy_busy_buffers_size 256k;
         proxy_temp_file_write_size 256k;
         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
         proxy_max_temp_file_size 128m;
         #proxy_cache mycache;                                
         #proxy_cache_valid 200 302 1h; 
         #proxy_cache_valid 301 1d;
         #proxy_cache_valid any 1m;
        }

 location /uatxcd/ {
         proxy_pass http://172.16.50.184:50002/;
         proxy_redirect off ;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header REMOTE-HOST $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_connect_timeout 300;
         proxy_send_timeout 300;
         proxy_read_timeout 600;
         proxy_buffer_size 256k;
         proxy_buffers 4 256k;
         proxy_busy_buffers_size 256k;
         proxy_temp_file_write_size 256k;
         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
         proxy_max_temp_file_size 128m;
         #proxy_cache mycache;                                
         #proxy_cache_valid 200 302 1h; 
         #proxy_cache_valid 301 1d;
         #proxy_cache_valid any 1m;
        }

 location  /devxcd/xcdcomment/ {
         proxy_pass http://172.16.50.73:9997/;
        }

 location  /fvtxcd/xcdcomment/  {
         proxy_pass http://172.16.50.73/9997/;
        }

 location  /uatxcd/xcdcomment/  {
         proxy_pass http://172.16.50.73/9997/;
        }
}


上面配置匹配/devxcd/xcdcomment/, /fvtxcd/xcdcomment/, /uatxcd/xcdcomment/的上下文代理后, 訪問:
https://uatbob-vfc.kevin.com/devxcd/xcdcomment/images/example_doorPlate.jpg    訪問正常打開
https://uatbob-vfc.kevin.com/fvtxcd/xcdcomment/images/example_doorPlate.jpg    訪問出現404
https://uatbob-vfc.kevin.com/uatxcd/xcdcomment/images/example_doorPlate.jpg    訪問出現404

解決: 添加proxy_redirect配置項

修改后的配置
[root@uatinner-lb01 vhosts]# cat uatbob-vfc.kevin.com.conf      
server {
      listen      443;
      server_name uatbob-vfc.kevin.com;

      ssl on;
      ssl_certificate /data/nginx/conf/ssl/ssl.kevin.com.crt;
      ssl_certificate_key /data/nginx/conf/ssl/ssl.kevin.com.key;
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      ssl_session_cache    shared:SSL:1m;
      ssl_session_timeout  5m;
      ssl_ciphers  ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;
      ssl_prefer_server_ciphers  on;
    
      access_log  /data/nginx/logs/uatbob-vfc.kevin.com-access.log main;
      error_log  /data/nginx/logs/uatbob-vfc.kevin.com-error.log;
    
 location /devxcd/ {
         proxy_pass http://172.16.50.16:50002/;
         proxy_redirect off ;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header REMOTE-HOST $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_connect_timeout 300;
         proxy_send_timeout 300;
         proxy_read_timeout 600;
         proxy_buffer_size 256k;
         proxy_buffers 4 256k;
         proxy_busy_buffers_size 256k;
         proxy_temp_file_write_size 256k;
         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
         proxy_max_temp_file_size 128m;
         #proxy_cache mycache;                                
         #proxy_cache_valid 200 302 1h; 
         #proxy_cache_valid 301 1d;
         #proxy_cache_valid any 1m;
        }

 location /fvtxcd/ {
         proxy_pass http://172.16.50.75:50002/;
         proxy_redirect off ;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header REMOTE-HOST $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_connect_timeout 300;
         proxy_send_timeout 300;
         proxy_read_timeout 600;
         proxy_buffer_size 256k;
         proxy_buffers 4 256k;
         proxy_busy_buffers_size 256k;
         proxy_temp_file_write_size 256k;
         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
         proxy_max_temp_file_size 128m;
         #proxy_cache mycache;                                
         #proxy_cache_valid 200 302 1h; 
         #proxy_cache_valid 301 1d;
         #proxy_cache_valid any 1m;
        }

 location /uatxcd/ {
         proxy_pass http://172.16.50.184:50002/;
         proxy_redirect off ;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header REMOTE-HOST $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_connect_timeout 300;
         proxy_send_timeout 300;
         proxy_read_timeout 600;
         proxy_buffer_size 256k;
         proxy_buffers 4 256k;
         proxy_busy_buffers_size 256k;
         proxy_temp_file_write_size 256k;
         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
         proxy_max_temp_file_size 128m;
         #proxy_cache mycache;                                
         #proxy_cache_valid 200 302 1h; 
         #proxy_cache_valid 301 1d;
         #proxy_cache_valid any 1m;
        }

 location  /devxcd/xcdcomment/ {
        proxy_pass http://172.16.50.73:9997/;
        proxy_redirect  http://http://172.16.50.73:9997/ https://uatbob-vfc.kevin.com/devxcd/xcdcomment/;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout 300;
        proxy_send_timeout 300;
        proxy_read_timeout 600;
        proxy_buffer_size 256k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;
        proxy_temp_file_write_size 256k;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
        proxy_max_temp_file_size 128m;
        }

 location  /fvtxcd/xcdcomment/  {
        proxy_pass http://172.16.50.73:9997/;
        proxy_redirect  http://http://172.16.50.73:9997/ https://uatbob-vfc.kevin.com/fvtxcd/xcdcomment/;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout 300;
        proxy_send_timeout 300;
        proxy_read_timeout 600;
        proxy_buffer_size 256k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;
        proxy_temp_file_write_size 256k;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
        proxy_max_temp_file_size 128m;
        }

 location  /uatxcd/xcdcomment/  {
        proxy_pass http://172.16.50.73:9997/;
        proxy_redirect  http://http://172.16.50.73:9997/ https://uatbob-vfc.kevin.com/uatxcd/xcdcomment/;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout 300;
        proxy_send_timeout 300;
        proxy_read_timeout 600;
        proxy_buffer_size 256k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;
        proxy_temp_file_write_size 256k;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
        proxy_max_temp_file_size 128m;
        }
}

修改后, 訪問:
https://uatbob-vfc.kevin.com/devxcd/xcdcomment/images/example_doorPlate.jpg    訪問正常打開
https://uatbob-vfc.kevin.com/fvtxcd/xcdcomment/images/example_doorPlate.jpg    訪問正常打開
https://uatbob-vfc.kevin.com/uatxcd/xcdcomment/images/example_doorPlate.jpg    訪問正常打開


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM