记一次nginx转发回环
一、需求流程
有业务需求需要在源站将部分指定客户,将其请求转发到另外一个域名,且不能重定向。
域名1:lzj.xxx.cloud,域名2:www.xxx.cloud
二、nginx配置
1.原本错误配置
location / {
set $match_ip 0;
if ($http_x_forwarded_for ~ "112.96.56.214"){
proxy_pass https://www.xxx.cloud;
}
if ($match_ip ~ 0) {
return 405;
}
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffering off;
}
2.想法:
判断是112.96.56.214来的请求时,转发至域名2,不是时,则响应正常服务(测试模型暂用405替代)
3.运行结果是报400
4.日志
查看nginx后台日志是请求不断在代理服务器ip和域名1源站服务器ip循环,因此判断应该是回环导致请求头过大报错。
5.错误猜想
nginx在proxy_pass转发新的域名时,还会加载后面的命令,把原本域名1的$host赋值给请求头的HOST,然后下一跳代理服务器里server_name根据请求的HOST字段匹配命中域名1,因此变成了一个回环,不断回环过程中请求头大小超过极限,然后报400
三、修正
1.直接指定HOST
if ($http_x_forwarded_for ~ "112.96.56.214"){
set $match_ip 1;
proxy_set_header HOST "www.xxx.cloud";
proxy_pass https://www.xxx.cloud;
}
但是报错了,location模块的if里不允许使用proxy_set_header
2.迂回指定HOST
location / {
set $match_ip 0;
set $host_test $host;
if ($http_x_forwarded_for ~ "112.96.56.214"){
set $match_ip 1;
set $host_test "www.xxx.cloud";
proxy_pass https://www.xxx.cloud;
}
if ($match_ip ~ 0) {
return 405;
}
proxy_set_header HOST $host_test;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffering off;
}
将$host赋值给一个变量,然后在if分支里改变值,最后将变量的值赋值给请求头的HOST里,最后请求成功。