nginx redirect and basic auth woes - nginx

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?

Related

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?

Password lock site except for certain routes running nginx

We have a server we don't want Google to index or anyone else to get access to unless they have a password.
How can I directory lock the entire server except for very specific routes used by external scanning services?
For instance, example.com/test should output a response from the framework without blocking but any other URL should ask for a password to get any content response.
I know how to do this with Apache using .htpasswd, but I need to be able to do it on nginx while whitelisting a specific route.
This will enable /test/ to respond without needing any authentication and every other request will need authentication.
server {
auth_basic "Administrator Login";
auth_basic_user_file /var/www/static/.htpasswd;
location /test/ {
auth_basic off;
}
}
Like this:
server {
...
auth_basic "Enter password";
auth_basic_user_file path/to/htpasswd;
location /test/ {
auth_basic off;
}
}

Proxy_Pass using Nginx on windows

i am trying to use nginx for my hosted website on Azure using location. but even if i configure Nginx for google, i get a 404.
location /master
{
proxy_pass http://www.google.com;
}
See this thread for url details on proxy_pass
Nginx proxy_pass only works partially
Your config
location /master
{
proxy_pass http://www.google.com;
}
Send /master also as the part of the url. Which means you are trying to go to http://www.google.com/master. So this won't work as it is a 404. But if you add trailing / to both your locations
location /master/
{
proxy_pass http://www.google.com/;
}
The /master will not be sent as the request url. Also this would just work for a brief moment as you will get a 301 to https://www.google.com. So better is to use proxy_pass https://www.google.com/;

NGINX unexpected behaviour with location directive and proxy_pass

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.

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.

Resources