Nginx location rules conflict with controller - nginx

So I have an nginx rule location set like this:
location /foo {
proxy_pass http://<a-service-discovery-url>/foo/;
proxy_redirect default;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Then I have a controller url like:
/foo-bar/bizz
The weird thing is that when I hit the controller in /foo-bar/bizz I get redirected to /foo again which is not desired.
I've tried many rule combinations all resulting in undesired behaviors:
location /foo/
or
location = /foo
or
location = /foo/
Also any regex defined with ~ won't work because the proxy_pass contains the world foo which is in the location rule.
having the trailing slash is not desired because then the user will have to explicitly write it.
Any help would be appreciated.
Thanks.

Have you tried dropping the trailing slash from the proxy_pass url when you add it to the location.
location /foo/ {
proxy_pass http://<a-service-discovery-url>/foo;
proxy_redirect default;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Related

nginx url rewrite mainting GET parameters

I would like to rewrite a path destination to another address and port but I want to maintain all the GET parameters.
The number of GET parameters is variabile and I want to keep all of them.
Something like this
redirect this
https://test.com/customPath/file.php?test1=1&test2=dsa&....
to
https://testrewrite.com:5302?test1=1&test2=dsa&....
In the test.com directive I wrote something like this.
location /customPath/file.php {
rewrite /(.*) /(.*) break;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Origin http://$host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://testrewrite.com:5302;
proxy_pass_header Server;
}
But obviusly it doesn't works. Any help?

Not able to see URL without trailing slash in NGINX

I know that this is a common issue in NGINX and there are many threads about that.
Issue:
When accessing the URL http://localhost/var without trailing slash is working with my current config. However, I need to add 2 locations (one with trailing slash and second one without trailing slash).
If i try accessing the URL with trailing slash, it is being redirected correctly and page is displayed correctly.
The issue comes when i try accessing the second URL:
http://localhost/var/api/app/v2
I did the same, adding two locations (one with trailing slash and second one without trailing slash). However, looks like the rewrite that i included inside server block is making a conflict as the url has some stuff behind "var". I am getting an 404 error.
This is my current config file:
server {
listen 8080;
listen [::]:8080;
server_name localhost;
rewrite ^/(.*)/$ /$1 permanent;
absolute_redirect off;
access_log /var/log/nginx/access.log main;
##location 1##
location /##var##/ {
set $dash local.##var##.svc;
rewrite ^/##var##(.*)$ $1 break;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://$dash:8080;
auth_basic_user_file /etc/apache2/dash_auth;
}
location /##var## {
set $dash local.##var##.svc;
rewrite ^/##var##/(.*)$ $1 break;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://$dash:8080/;
auth_basic_user_file /etc/apache2/dash_auth;
}
##location 2##
location /##var##/api/app/v2/ {
set $nu local2.##var##.svc;
rewrite ^/##var##/api/v2/app/(.*)$ /app/$1 break;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://$nu:6000;
auth_basic_user_file /etc/apache2/dash_auth;
}
location /##var##/api/app/v2 {
set $nu local2.##var##.svc;
rewrite ^/##var##/api/app/v2(.*)$ /app/$1 break;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://$nu:6000/;
auth_basic_user_file /etc/apache2/dash_auth;
}
}
This is working when accessing the URL:
http://localhost/var
but not when accessing the URL:
http://localhost/var/api/app/v2
i think the conflict is regarding the rewrite in the server but not sure how can i fix that.
I tried to add the rewrite inside the location for /var/ but not working as expected. I was thinking about include a specifyc rewrite for every location but not sure if this is gonna work.
Also I trid to add these two rewite rules in server block, but not working:
rewrite ^/api/app/(.*)/$ /api/app/$1 permanent;
rewrite ^/(.*)/$ /$1 permanent;
Regarding the ports, that is something currently working. i mean without including any modification in the nginx config it is working (just with URL with trailing slash although).
Change
proxy_pass http://$dash:8080;
To
proxy_pass http://$dash:8080/;
Also your default nginx location should looke like this
location / {
auth_basic_user_file /etc/apache2/dash_auth;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://$dash:8080/;
}

NGINX: alias or proxy based on query string

I'm looking for a way to allow a proxy_pass when certain querystrings are in the url and send the URI to an alias the rest of the time.
Here's how I have the in one environment, the location block is configured like this:
location /my-route {
alias /assets/coming-soon/;
index index.html;
}
In another, it's configured like this:
location /my-route {
proxy_pass http://tool_servers/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
I want to combine the two and pass the bare uri to to the coming-soon page, but URIs with ?filter=test to tool_servers.
Proxy config cannot go inside an if ($arg_filter = "test") block (I tried). Is there another work-around?

More accurate nginx location matching

I have the following nginx rule
location /api {
proxy_pass http://flask:5000/api;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
It will match the following path, which is what I'm expecting
http://localhost/api
http://localhost/api/
http://localhost/api/a
http://localhost/api?
http://localhost/api?name=value
However, it will also match the following, which I'm not expecting
http://localhost/apii
http://localhost/apiX
May I know how can I avoid from matching unwanted http://localhost/apii and http://localhost/apiX and http://localhost/apiXX and ...
This requires two location blocks - one matching specifically /api and one for everything in the path /api/. In this way urls like /apio will not be captured.
Example:
location = /api {
proxy_pass http://flask:5000/api;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
#Querystrings and /api, matches the first, any /api/* matches this one
location /api/ {
proxy_pass http://flask:5000/api;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Reference http://nginx.org/en/docs/http/ngx_http_core_module.html#location
One possibility is to use a regular expression. As the proxy_pass is not actually transforming the URI, the uri element can be safely removed.
location ~ ^/api($|/) {
proxy_pass http://flask:5000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Note that regular expression location blocks are evaluated in order. See this document for details.
It's actually really simple.
Just change location /api { to location /api/ {
Nginx will add a trailing slash to any request ending /api so there is no need to add a separate block for them. This block will behave as you expected your original one to.

forward matched specific location and proxy redirect it in nginx

I am trying to forward specific uri if matched to backend in nginx. For example
forward https://www.hostname.com/*/a/b/c to https://int.hostname.com/*/a/b/c (Where * is a variable auto populated from regex)
Current configuration looks like below and have no idea how to proceed on above
location /a/b/c/ {
proxy_set_header Host $proxy_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 180m;
proxy_pass http://int.hostname.com/v2/e/t/a/b/c;
proxy_redirect default;
}
If you want your location to match any URI that ends with /a/b/c/, you will need to use regular expression syntax. See this document for details.
The URI suffix of the proxy_pass statement is optional. In the absence of a URI suffix, the original URI will be passed unmodified. See this document for details.
For example:
location ~ /a/b/c/$ {
...
proxy_pass http://int.hostname.com;
...
}

Resources