zl程序教程

您现在的位置是:首页 >  云平台

当前栏目

使用Nginx实现根据IP匹配指定URL

NginxIP 实现 使用 指定 url 匹配 根据
2023-06-13 09:15:45 时间

业务需求

业务和开发同事需要我这边做一条规则,所有访问ip为非上海、广州office外网ip,url为http://test.com/fuck/index.html的请求都跳转到http://test.com/index.html。然后所有在上海和广州office的外网IP访问http://test.com/fuck/index.html依然还是http://test.com/fuck/index.html。这样就可以在生产上做隔离,不影响其他用户的服务。

注:因为目前生产上的Nginx没有做lua支持,所以就无法通过使用lua来实现该需求,也没有安装geoip,所以也无法用模块来支持,只能原生的。

原始的nginx配置

upstreamservice_test{
server127.0.0.1:8080;
}
server
{
listen80;
server_nametest.com;
indexindex.htmlindex.php;
root/tmp/test.com;
error_page404http://test.com/404.html;
error_page502http://test.com/502.html;
error_page500http://test.com/500.html;
location~*\.(gif|jpg|jpeg|png|css|js|ico|txt|svg|woff|ttf|eot)$
{
rewrite^(.*)$/static$1break;
root/tmp/test.com;#
expires1d;
}
location~*\.(html|htm)$
{
rewrite^(.*)$/static$1break;
roo/tmp/test.com;#
expires900s;
}
location/{
proxy_passhttp://service_test;
include/opt/conf/nginx/proxy.conf;
}

修改后的Nginx配置

upstreamservice_test{
server127.0.0.1:8080;
}
server
{
listen80;
server_nametest.com;
indexindex.htmlindex.php;
root/tmp/test.com;
error_page404http://test.com/404.html;
error_page502http://test.com/502.html;
error_page500http://test.com/500.html;
location~*\.(gif|jpg|jpeg|png|css|js|ico|txt|svg|woff|ttf|eot)$
{
rewrite^(.*)$/static$1break;
root/tmp/test.com;#
expires1d;
}
location~*\.(html|htm)$
{
rewrite^(.*)$/static$1break;
roo/tmp/test.com;#
expires900s;
}
set$flag0;
if($request_uri~*"^/fuck/\w+\.html$"){
set$flag"${flag}1";
}
if($remote_addr!~*"192.168.0.50|192.168.0.51|192.168.0.56"){
set$flag"${flag}2";
}
if($flag="012"){
rewrite^/index.htmlpermanent;
}
location/{
proxy_passhttp://service_test;
include/opt/conf/nginx/proxy.conf;
}

在实现需求的过程中出现的问题

把if指令和proxy_pass都放在location下面的话,if指令里面的内容不会执行,只会执行proxy_pass。

location/{
if($remote_addr!~*"192.168.0.50|192.168.0.51|192.168.0.56"){
rewrite^/index.htmlpermanent;
}
proxy_passhttp://service_test;
include/opt/conf/nginx/proxy.conf;
}

if指令下面使用proxy_pass指令问题

像下面这样使用会报错,错误的方式:

if($remote_addr~*"192.168.0.50|192.168.0.51|192.168.0.56"){
proxy_passhttp://test.com/fuck;
}

正确的方式:

if($remote_addr~*"192.168.0.50|192.168.0.51|192.168.0.56"){
proxy_passhttp://test.com$request_uri;
}

或是

if($remote_addr~*"192.168.0.50|192.168.0.51|192.168.0.56"){
proxy_passhttp://test.com;
}


如果你是直接另外启动一个location的话,比如启动如下location:

location/fund{
if($remote_addr!~*"192.168.0.50|192.168.0.51|192.168.0.56"){
rewrite^/index.htmlpermanent;
}
}

这样的方式也是不支持的,当用IP192.168.0.50访问的时候,没有达到我们的业务需求,会报错400

注:各位有其他好的建议,欢迎探讨。