NGINX unexpected behaviour with location directive and proxy_pass - nginx

I have a NGINX configuration file to serve a Website with static files and via a development Server.
static -> http://localhost:8080
dev webserver -> http://localhost:8080/dev
There are several other services which I bind to different location directives.
Here is a snipped of the configuration file.
...
upstream qgis {
server qgis-spcluster_server:80;
}
...
server {
listen 8080;
server_name localhost;
location / {
root /usr/share/nginx/html/build;
index index.html index.htm;
auth_basic "Zugangskontrolle";
auth_basic_user_file /etc/nginx/.htpasswd;
}
location /dev/ {
proxy_pass http://web_app/;
auth_basic "Zugangskontrolle";
auth_basic_user_file /etc/nginx/.htpasswd;
}
location /static/ {
proxy_pass http://web_app/static/;
}
location /qgis/ {
proxy_pass http://qgis/;
}
location /apex/ {
proxy_pass http://apex/apex/;
auth_basic "off";
}
...
Everything works as expected until i open the URL to get the static files. After that all other URLs leads to the static files.
http://localhost:8080/apex -> Apex Service
http://localhost:8080 -> static Website
http://localhost:8080/apex -> static Website
For me everything looks ok, but indeed something is not ok.
The Basic_Auth produce another unexpected behaviour.
http://localhost:8080 -> basic auth -> success -> static website
http://localhost:8080/apex -> basic auth -> it is not possible to get rid of the pop up
So in the moment I'm a little bit clueless how to solve this issue.

Please remove the trailing / from your location directives or provide / when you access them.
Nginx looks for the longest prefix match location. When you access http://localhost:8080/apex, it's routed to / because /apex/ is not the prefix of /apex
Documentation of location is here

I tried now several things, but nothing really worked well. So I decided to create a second server block for all location directives which are problematic with my current setup.
Probably this is not the best solution, because I have still no idea why I get these problems. But it works now and that counts for me.

Related

Nginx reverse proxy return 502

I'm very new to nginx and server game and i'm trying to setup a reverse proxy. Basically what i need is when i enter my server ip it should open a particular website (Ex: https://example.com).
So for example if i enter my ip (Ex: 45.10.127.942) it should open the website example.com , but the url should remain as http://45.10.127.942.
I tried to set my server configuration as follows but it returns a 502 error.
server {
listen 80;
location / {
proxy_pass http://example.com;
}
}
It returns a 502 error. Can you please explain what i need to do?
You can have something like this in your configuration file:
server {
root /var/www/html;
server_name _;
location / {
try_files $uri $uri/ /index.html;
}
}
Place the index.html file in root folder specified.
Then just restart the NGINX and it should work.
What is the problem with your configuration file is you should not proxy_pass.
If you want to open the other website, you should have DNS record pointing to that IP. What actually happens is the thing you are trying to do is known as CLICKJACKING. For more details, search CLICKJACKING on google and you will find a lot of references.

How to route different webservers to different URL using nginx

creating a website for my self and need to host projects.
Basically, i hhave different projects with different framework. ie, Flask, Django, Node.JS and some html file projects. I would like to host them at projects.domain.com/<project name>
I tried to set server_name projects.domain.com/asdf but in error.log it says, server name "projects.domain.com/asdf" has suspicious symbols
Next up, i tried to nest location blocks (which i presume isn't how its supposed to be)
location /asdf {
location /static/ {
root blah blah;
}
location / {
..
proxy_pass http://localhost:3000 ;
}
}
But, this errors out saying location static is outside asdf
Some suggested to alias instead of root in the location /static/ block, but that doesnt work too.
Any help is appreciated :)
First of all a server_name can not contain URI segments. So a hostname or IP should be used as a value.
If you want to mix different local directories and proxy-locations a configuration could look like this.
Notice: Your location URI (/one, /two) will be appended to the root path.
The root directive can be used in every location block to set the document root.
http://nginx.org/en/docs/http/ngx_http_core_module.html#root
This is the reason why alias exists. With alias the location will not be part of the directory path. Check this out:
http://nginx.org/en/docs/http/ngx_http_core_module.html#alias
server {
server_name project.domain.com;
listen 80;
location / {
proxy_pass http://localhost:3000;
}
location /one/ {
alias/var/www/html/project1/;
index index.html;
}
location /two/ {
alias/var/www/html/project2/;
index index.html;
}
}

Nginx - how to proxy_pass particular url to a different host while keeping context?

I have a fairly simple nginx conf for a front-end and backend application:
server {
listen 8080;
server_name nginx_server;
port_in_redirect off;
location / {
root /dir/html;
index index.html index.htm;
}
location /api/ {
proxy_pass http://my-api:8080/;
}
}
My main host is https and this works fine. When I hit https://myapp.com/api/a/b/c, my backend receives /a/b/c, which is what I want.
Now, I want to send the requests to a particular /api context to a different server:
location /api/a/b {
rewrite /api/(.*) /$1 break;
proxy_pass http://another-api:8080;
}
So now, if I hit https://myapp.com/api/a/b?param=1 I want to hit http://another-api:8080/a/b?param=1 and also https://myapp.com/api/a/b/c/d should hit http://another-api:8080/a/b/c/d
This is working when I test using Postman, but for some reason, in Chrome, when my frontend app tries to hit https://myapp.com/api/a/b/c/d I get a console error: (blocked:mixed-content)
How can I fix this?

Nginx: how to add /something to a uri and still keep it working

I have a nginx instance running. My config is something like the following.
server {
listen 80;
listen 443;
location / {
...
proxy_pass http://127.0.0.1:8080;
...
proxy_redirect http://127.0.0.1:8080 example.com;
}
}
I have some software running in 8080 and I want that the user enters example.com/somepath and be able to be redirected to the root 127.0.0.1:8080 through my domain. The software should receive all urls without /somepath but the browser should still show /somepath in the name.
I am quite new so sorry for the basic question I could not find any relevant info on how to do this exactly: I tried rewrite rules and setting location /mysoftware { tests with no luck.
The client browser uses /somepath/... to access /...in the application. This means that nginx must rewrite the URI before passing it upstream.
The proxy_pass directive has a basic rewrite capability. See this document for details. For example:
location /somepath/ {
proxy_pass http://127.0.0.1:8080/;
...
}
Alternatively, you might use a rewrite ... break statement. See this document for details. For example:
location /somepath {
rewrite ^/somepath/?(.*)$ /$1 break;
proxy_pass http://127.0.0.1:8080;
...
}
The difficult part is preventing your application from breaking out of /somepath. The proxy_redirect directive can handle the 3xx responses from your application. But the location of resource files (.css and .js) and the target for hyperlinks, can cause problems for applications that are not aware that they need to stay inside a subdirectory.

nginx redirect and basic auth woes

I have a service (Plack) which listens on http://myhost.com:5000
I want to password protect access to it with Basic Auth
When I set a server directive in the nginx conf file I get a conflict with Plack (can't bind to 0.0.0.0:5000 because it is use by Plack, and vice versa). So this brings me nowhere.
Then I enabled Basic Auth in the conf file with the location directive as :
server {
location / {
proxy_pass http://localhost:5000;
auth_basic "Restricted";
auth_basic_user_file /home/userx/.htpasswd;
}
}
which when nginx "/" is hit it redirects it to port 5000 and asks for username/password. But my app relies on the url including the port (http://myhost.com:5000/) to find the resources and the port is stripped off from the request, so what it ends up is a http://myhost.com and I get a 404 on all resources/css/images/javascripts etc. Tried various directives like port_redirection etc.
I tried URL rewriting with :
location / {
auth_basic "Restricted";
auth_basic_user_file /home/userx/.htpasswd;
rewrite ^/(.*) https://example.com/$1 permanent;
}
which gets the desired result (http://myhost.com:5000) and all resources are found but basic auth never kicks off so I never get a prompt asking for a username /password
As a final attempt it tried to protect the url with a direct
location http://localhost:5000 {
auth_basic "Restricted";
auth_basic_user_file /home/userx/.htpasswd;
}
but that did not work either.
Can someone help?

Resources