nginx 根据一个“位置”中的 URI 阻止 IP

nginx 根据一个“位置”中的 URI 阻止 IP

目前有一个地点被封锁/

  location / {
    root  /var/www/docs;
    proxy_pass  http://backend;
    proxy_buffering     on;
    proxy_buffer_size   64k;
    proxy_buffers       256   64k;
  }

需要通过IP进行过滤。

理想情况下,为了减少相同指令的重复次数location,我想在location块内执行测试

  location / {

    if ($uri ~ '^/(abc|def|ghi)') {
        allow 10.0.0.0/8;
        allow 1.2.3.4;
        deny all;
    }

    root  /var/www/docs;
    proxy_pass  http://backend;
    proxy_buffering     on;
    proxy_buffer_size   64k;
    proxy_buffers       256   64k;
  }

allow不幸的是, /指令似乎deny不能在块内使用if

/etc/nginx/sites-enabled/mysite:20 中不允许使用“allow”指令

是否有一种优雅的方式来执行测试而无需重复location块?

(喜欢

  location ~ /(abc|def|ghi) {

        allow 10.0.0.0/8;
        allow 1.2.3.4;
        deny all;

        ... 5 other lines root,proxy...
   }

  location  / {

        ... 5 other lines root,proxy...
   }

答案1

就像 coredump 所说的那样,不,使用多个位置。

但可以使location块的内容不那么重复。这里的关键是location包含rootproxy_...指令的命名块。

例如:

location / {
  try_files $uri @proxy;
}
location ~ /(abc|def|ghi) {
  allow 10.0.0.0/8;
  allow 1.2.3.4;
  deny all;

  try_files $uri @proxy;
}
location @proxy {
  root  /var/www/docs;
  proxy_pass  http://backend;
  proxy_buffering     on;
  proxy_buffer_size   64k;
  proxy_buffers       256   64k;
}

可能更好的方法是将root指令放在所有location块之外。

答案2

首先,你必须定义一个变量来保存你的 IP 过滤器。这将进入httpnginx 配置部分:

map $remote_addr (or $http_x_forwarded_for if behind a proxy) $allowed {
        default deny;
        ~\s*111.222.333.444$ allow;
        ~\s*333.444.555.*$   allow;
    }

然后在服务器部分中,你编写了 if 构造并根据变量的内容过滤访问位置$允许

location / {
        if ( $allowed = "deny" ) { return 403; }
        #...
    }

答案3

通常在这种情况下可以帮助“嵌套位置”......

location / {
   root /var/www/docs;
   allow all;

   location /admin {
       deny 1.2.3.4;
   }

}

... 但并非所有指令都会在嵌套位置中继承。遗憾的是,但确实如此proxy_pass,以及类似的指令不会被继承... 因此,之前提出的解决方案(使用 @namedlocation)在这种情况下是正确的。当然,fastcgi_pass您也可以使用“proxy_pass block”指令。include

答案4

不。使用多个locations,它可能看起来很丑,但你会减少如果疯狂

还要记住,nginx 首先处理正则表达式匹配,如果没有匹配,它会尝试最具体的文字位置,这是location /一种全部捕获 位置。了解这一点也许可以减少所需的位置数量。看看本文档查看请求是如何被处理的。

相关内容