Deny all location ... except
Francis Daly
francis at daoine.org
Mon Oct 26 13:00:10 UTC 2020
On Wed, Oct 21, 2020 at 03:50:03PM -0300, Rejaine Silveira Monteiro wrote:
Hi there,
> I want to deny all access from external network to /prod and /hml
> locations, except from some arguments like "?TEST" or "=TEST"
I don't see a straightforward way to do this, I'm afraid.
For a non-straightforward way: It is possible to use "map" to create a
variable to indicate whether or not you want this request to be blocked;
and then use that variable instead of your allow/deny lists. But that will
only be useful if you can find patterns that correctly match everything
you want in the block/no-block decision.
(And it is sort-of doing in config, what the application already has
facilities to do -- but your special use case might make that worthwhile.)
> https:/domain.com/prod/* (allow to localnet, deny to external users), but...
> https:/domain.com/prod/INDEX.apw?op=01&SERVICE=TEST (allo to all)
> https:/domain.com/prod/INDEX.apw?TEST=123 (allow to all)
> https:/domain.com/prod/something/TEST/index.html (allow to all)
For example, if your version of "localnet" can be expressed in a small
number of regex patterns, then you could try something like
map "$remote_addr-$request_uri" $block_this_request {
default 1;
~^127\.0\.0\.1-/ 0;
}
which, when used, would have the effect of allowing everything from
127.0.0.1 and blocking everything else. Your case might want something
like ~^192\.168\. to allow addresses that match that pattern.
(If your "localnet" is not simple, then "geo" might be usable to set an
always-allow variable based on source IP instead; and *that* could be
used in the continuation of this example.)
Next, that same "map" should include whatever patterns you want to allow
from anywhere -- perhaps the string TEST anywhere in the url, or the
string TEST= after a ? in the url; or even a complete list of urls or
url prefixes that you want to allow; and set the $block_this_request
variable to 0 in those cases. For example, for "/TEST/" or "TEST=" or
"=TEST" anywhere in the url, you could add the three lines
~/TEST/ 0;
~TEST= 0;
~=TEST 0;
inside the map.
> I tried to use something like " if ($args = TEST) { allow all;}",
> but Nginx gives error " directive is not allowed here"
Now that you have set $block_this_request: in the two location{}s that
you want it to take effect, remove the "allow" and "deny" lines, and
instead add
if ($block_this_request) { return 403; }
which should have the same effect as the previous deny.
> location /prod {
> allow localnet;
> deny all;
> proxy_pass http://web1.domain:8080/prod;
> }
> location /hml {
> allow localnet;
> deny all
> proxy_pass http://web1.domain:8081/hml;
> }
>
> I appreciate any help
It does not strike me as especially elegant; but if it does what you want,
efficiently enough for your use case, it may be adequate. At least until
someone suggests an alternative.
Good luck with it,
f
--
Francis Daly francis at daoine.org
More information about the nginx
mailing list