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.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.40:9080; 
       } 
   } 

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

前端的Nginx负责把http://www.kevin.com/grace/Server/开头的url反向代理到后端的http://10.0.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.40/;  
    proxy_redirect http://www.kevin.com/ /grace/;  
}  

============================================================================== 如下启用了proxy_redirect配置(http->https),配置中就不需要"proxy_set_header Host $host;",即不需要"添加发往后端服务器的请求头"的配置了

[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;
 
        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;
 
        } 
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏惨绿少年

SSH服务详解

第1章 SSH服务 1.1 SSH服务协议说明 SSH 是 Secure Shell Protocol 的简写,由 IETF 网络工作小组(Network Wo...

49700
来自专栏码代码的陈同学

使用jasypt加密Spring Boot应用中的敏感配置

本文讲述了在Spring Boot/Spring Cloud应用中使用jasypt来加密properties。

34350
来自专栏运维一切

sentry部署整理 原

sentry是python开发的一个应用,使用python uWSG框架运行,所有安装完sentry要记得在nginx的代理上禁用掉/admin路径,不然uws...

27210
来自专栏极客生活

macOS Interface Inspector逆向破解

Interface Inspector 本身是一个逆向的辅助工具,可以attach到正在执行的应用上,查看界面元素在内存中的地址。

14210
来自专栏Linux驱动

Linux-kill命令(11)

kill:指定将信号发送给某个进程,常用来杀掉进程,可以通过ps、top命令来查看进程 在默认情况下: 采用编号为15的TERM信号。TERM信号将终止所有不能...

24450
来自专栏潇涧技术专栏

Using Git with multiple Public Keys

很多时候,如果我们在多个网站有了Git账号,例如Github、GitCafe、CodingNet等,当我们与不同网站的代码库进行连接的时候可能会因为我们没有配置...

8220
来自专栏緣來來來

申请Let's Encrypt通配符证书

Let's Encrypt支持通配符证书了,也就是说你只需要为你的网站申请*.example.com这样一个证书,所有的子域名都可以支持,下面介绍下申请方法:

67020
来自专栏tiane12

Mac OS X无法更改桌面背景解决方法

19020
来自专栏cmazxiaoma的架构师之路

MyEclipse使用Git进行Push to Upstream报错 学习笔记

10520
来自专栏Android相关

Gradle解决多lib冲突

在引入第三方jar包的时候,可能会遇到很多库的冲突,例如均使用了OkHttp,RxJava等等,在打包的时候就会遇到Class多个定义的问题。而目前Androi...

29020

扫码关注云+社区

领取腾讯云代金券