Not able to see URL without trailing slash in NGINX - 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/;
}

Related

Nginx : Remove the trailing slash before params(?) and forward it and not redirect

I have url like /v1/path1/path2/?param1=a&param2=b.
I want this to be converted into /v1/path1/path2?param1=a&param2=b and forward it to the server.
I wrote a rewrite in Nginx conf but that is returning is 301 status code with a redirect which my clients are not able to handle.
So, can we check if the URL has an extra slash, then remove it and forward to the server using Nginx
I was able to solve this by adding rewrite ^/(.*)/$ /$1; to conf in location
server {
listen 80;
server_name mysite.com;
location / {
set $request_body_head '';
rewrite ^/(.*)/$ /$1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://localhost:8003;
}
}

nginx - rewrite location to root of server

I have this nginx.conf nginx configuration:
http {
...
upstream app_servers {
server admin;
}
upstream status_servers {
server status:5000;
}
# Configuration for the server
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
location / {
proxy_pass http://app_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;
}
location /api {
proxy_pass http://api_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;
}
}
}
/ is server to one server, and
/api to another api server.
The problem is with the second (the api server).
The calls are reaching /api/** while I want them to reach the root of the api server (basically remove the /api when calling the api server).
so calling
/api -> will reach / in the api server, and calling
/api/foo -> will reach /foo in the api server.
I guess I'm looking for some kind of rewrite rull for that(?)
I have tried Inside the /api location:
rewrite ^/api(.*) /$1 last;
but it didn't seem to work.
Any kind of help would be appreciated!
Solved it using rewrite ^/api(/.*)$ $1 break;
but I can't just using /api - it must be /api/ (with trailing /)
For me it's fine, interesting though if anyone knows how to have support for /api too.
I'm not sure you still need it...but I managed to avoid "/api/", by doing this:
rewrite /api(/|$)(.*) /$2 break;

Nginx location rules conflict with controller

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;
}

Avoid duplication in password protect URL with proxy in nginx

I have a Flask application served using gunicorn, and with NGINX on top of it. I want to use Basic Authentication (user/password) to protect all URL's starting with /admin, which is the back office, but still continue serving all other URLs with gunicorn without password.
Here is my current NGINX config:
server {
listen 80;
server_name example.com;
charset utf-8;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /admin {
auth_basic "Administrator Login";
auth_basic_user_file /home/app/.htpasswd;
# the following four directives are duplicated :(
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
If I don't duplicate the proxy_* directives in the second location block, then the URLs starting with /admin doesn't get forwarded to gunicorn and I get a 404.
Is there any way to avoid the configuration duplication? I tried location nesting but apparently in the end NGINX only "executes" a single location block.
The proxy_pass must be within the location block. However, there's no need to duplicate the proxy_set_header directives, they can be moved into the server block. So your mistake was simply the assumption that proxy_pass could live in the server block :-)

Nginx case insensitive URL and rewrite URL?

I have Nginx configured as reverse proxy
server {
listen 80;
server_name www.pluto.com;
location / {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080;
}
}
I need that the URL request from any combination of FOLDER1 (case insensitive) is rewrite from URL
http://www.pippo.com/FOLDER1/etc..etc..etc..
to (always lowercase folder1)
http://127.0.0.1/folder1/etc..etc..etc...
where etc..etc..etc. = anything that I need to keep
How can I do?
location ~* ^/folder1(?:/?)(.*) {
proxy_pass http://127.0.0.1:8080/folder1/$1$is_args$args;
}
(?:/?) says we may have one slash after folder1 which in that case we just ignore it. we then grab whatever remains by (.*) which will be placed in $1. then in the proxy_pass argument, we build the new URI: first we add what we had after folder1/ in the original URI and then we add all the arguments. so if your original URI is /folder1/test, the proxy_pass URI should be http://127.0.0.1:8080/folder1/test. do some experiments with the cases where you have parameters, e.g. /folder1/test?id=1. I'm not sure whether (.*) will capture the ?id=1 part too or not. if it does, then the proxy_pass should be changed to http://127.0.0.1:8080/folder1/$1.

Resources