Initial disclosure:
I'm new to nginx and struggling to understand its configuration principles; I have read a fair amount of the docs (including 'If Is Evil'), but still lack comprehension of many aspects. I intend to implement an api gateway in the near future for production, but desire to implement the below-described controls in straight nginx config, if possible, in the testing phase
Situation:
I have a service running behind an nginx reverse proxy at endpoint https://foobar.org/foo/
.
I wish to disallow all unauthenticated requests to the proxied server except for one specific endpoint; lets call it
/foo/anon_permitted
Problem:
I've tried to add an AND to the conditional within the location block like so :
`if ($http_authorization = "" && $request != https://foobar.org/foo/anon_permitted) { return 403; }`
However, nginx balks with an "invalid condition" error. [Note: I've tried various formatting permutations of the above, to no avail]
I've tried some other of the available variables ($request_url
, $uri
, $args
) from https://nginx.org/en/docs/varindex.html , but the result is the same.
Also, I'm aware that adding conditionals to the location block is explicitly advised against, so if there's a better way to go about this configuration altogether (aside from the aforementioned api gateway), I'm eager to learn it.
Question:
Is there a way to achieve the desired result, i.e., return 403 if condition 'a' and not condition 'b', using pure nginx configuration? And if so, how?
Current (working except for desired conditional) nginx conf shown below for reference:
server {
server_name foobar.org www.foobar.org;
root /usr/share/nginx/html;
index index.html;
try_files $uri /index.html;
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/foobar.org/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/foobar.org/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location /foo/ {
default_type application/json;
proxy_hide_header Content-Location;
add_header Content-Location /api/$upstream_http_content_location;
proxy_set_header Connection "";
proxy_http_version 1.1;
if ($http_authorization = "") { return 403; }
proxy_pass http://foo_upstream/;
}
}