Proxy_pass 为特定 IP 传递所有请求,但为所有其他 IP 提供静态文件

Proxy_pass 为特定 IP 传递所有请求,但为所有其他 IP 提供静态文件

我的 Web 应用程序前面有一个 nginx 代理。我想不时更新应用程序,并在更新期间让用户看到一个静态页面,告知他们应用程序正在停机。到目前为止都没有问题。

现在我还想使用 UI 测试框架测试应用程序,这需要在停机期间访问应用程序。注意:我现在负担不起测试服务器的设置。

我有一个运行 UI 测试的虚拟机,所以我想修改 nginx 配置,这样只有该 VM 可以访问该网站,所有其他 IP 都提供静态页面。

我的基本方法是在服务器块中使用 if 语句,该语句表示,如果$remote_addr不是,则使用 提供静态文件try_files。否则(在 VM 的情况下)所有流量都会以相同的方式进行。

我尝试过不同的解决方案,但是简单的解决方案无法实现,比如将try_files指令放在 if 语句中。

我还尝试过重写 URL(如果它来自 VM 以外的其他 IP),但这意味着所有 css 和 jpg 请求也会被重写。所以我最终得到了如下结果:

location ~* ^.+\.(jpg||png|css)$ 
{
    try_files $uri = 404;
}

if ( $remote_addr !~* <VM IP> ) {
  rewrite ^ https://example.com/static.html; 
}  

location /static.html
{
    try_files $uri /static.html = 404;
}
location /
{
# headers
proxy_pass <internal-server>; 
} 

在我看来,这是一种黑客行为,实际上根本不起作用。我正在寻找一个不同的、更简单的解决方案,来自之前做过类似事情的人。

我了解 nginxgeo模块,但我认为我并不真正需要它,也想让事情保持简单。

因此,如果未指定 IP,则基本问题是将所有流量重定向到静态页面。(请求 URL 可以相同,因此基于位置的解决方案对我来说不起作用)

答案1

您可以通过将所有静态内容放在一个通用 URI 前缀(例如/maintenance/...)下来简化配置。

例如:

location / {
    if ($remote_addr != '1.2.3.4') {
        rewrite ^ /maintenance/ last;
    }
    ...
    proxy_pass ...;
}
location /maintenance/ {
    root /path/to/root;
    index index.html;
}

维护页面位于/path/to/root/maintenance/index.html。资源文件位于同一目录中,可使用相对 URI(例如foo.css)或带前缀(例如/maintenance/foo.css)进行访问。

相关内容