There is currently a block of one location /
location / {
root /var/www/docs;
proxy_pass http://backend;
proxy_buffering on;
proxy_buffer_size 64k;
proxy_buffers 256 64k;
}
that needs to be filtered by IP.
Ideally, in order to reduce the number of repetitions of the same directives in location
, I would like to perform the test within the location
block
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;
}
Unfortunately, it seems the allow
/deny
directives cannot be used within a if
block.
"allow" directive is not allowed here in /etc/nginx/sites-enabled/mysite:20
Is there an elegant way to perform the test without repeating the location
blocks?
(like
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...
}
)
Like coredump said, no, use multiple locations.
But it is possible to make the contents of the
location
blocks less repetitive. The key here is a namedlocation
block which contains theroot
andproxy_...
directives.For example:
And probably even better would be to place the
root
directive outside all thelocation
blocks.First you have to define a variable that will hold your IP filters. This goes into the http section of the nginx config:
then in the server section you write the if construct and filter the access location by the contents of the variable $allowed:
Usually in such cases can help "nested locations" ...
... but not all directives inherited in nested locations. Sadly, but exactly
proxy_pass
,fastcgi_pass
and similar are not inherited... So solution proposed earlier (with @namedlocation) is correct in this case. You can also use a directiveinclude
for "proxy_pass block", of course.No. Use multiple
locations
, it may look ugly but you will end with less chance of if craziness.Also remember that nginx processes first the regex matches and if none matches it tries the most specific literal location, being
location /
kind of a catch all location. Knowing that you can maybe diminish the number of locations you need. Take a look at this doc to see how requests are processed.