Nginx basic HTML authentication on a subfolder - authentication

I need help applying basic HTML authentication to password protect a subfolder on my site - hosted by Digitalocean served using Nginx. I followed the tutorial - https://www.digitalocean.com/community/tutorials/how-to-set-up-http-authentication-with-nginx-on-ubuntu-12-10.
But my results are:
1. The entire site prompts for credentials rather than the specified subfolder, and
2. All the pages on the site can longer find css and js files.
Here's what I tried:
1) Generated a .htpasswd file in the subfolder,
2) Added a location block in the nginx.conf file (see below), and
3) Reloaded nginx.
location / {
auth_basic "Restricted";
auth_basic_user_file /var/www/pepperslice/current/public/ps/jeffaltman/.htpasswd;
}
The complete nginx.config file is as follows:
upstream unicorn {
server unix:/tmp/unicorn.pepperslice.sock fail_timeout=0;
}
server {
listen 80 default;
root /var/www/pepperslice/current/public;
try_files $uri/index.html $uri #unicorn;
location = /images {
root /var/www/pepperslice/current/public/images;
}
location #unicorn {
proxy_pass http://unicorn;
}
location / {
auth_basic "Restricted";
auth_basic_user_file /var/www/pepperslice/current/public/ps/jeffaltman/.htpasswd;
}
error_page 500 502 503 504 /500.html;
}
At the moment, the location block I added is commented out.
I am seeking help on how I can:
1. password protect the subfolder pepperslice.com/ps/jeffaltman, and
2. password protect other subfolders using different username and password combinations.
Also, any ideas why the css and js paths failed? I am guessing once the authentication problem is fixed, the css/js path problem will go away.
Thanks.

After some more research I found a solution and solved the issue. This guide is where I found it - see section 3 - https://www.howtoforge.com/basic-http-authentication-with-nginx
Instead of the location block starting with "location / {...}" (root for site), for a subfolder it should start with the subfolder path. For example:
location /ps/jeffaltman {
auth_basic "Restricted";
auth_basic_user_file /var/www/pepperslice/current/public/ps/jeffaltman/.htpasswd;
}
Also the css and js path problem disappeared.
Cheers.

Related

How to fix incorrect nginx s3 reverse proxy paths?

I'm working on an nginx s3 reverse proxy container image to proxy frontend files (Angular apps) from s3 behind an Application Load Balancer. The frontend files are located in the specific folder of the given app name in the s3 bucket. These are angular apps which are built using standard angular commands. The dist contents are uploaded to s3 and then the ALB route paths, along with the nginx locations map to those app folders in s3. For example, here is my nginx conf file:
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/ssl/nginx-server.crt;
ssl_certificate_key /etc/ssl/nginx-server.key;
server_name timemachine.com;
sendfile on;
default_type application/octet-stream;
resolver 8.8.8.8;
server_tokens off;
location ~ ^/app1/(.*) {
proxy_http_version 1.1;
proxy_buffering off;
proxy_ignore_headers "Set-Cookie";
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header x-amz-meta-s3cmd-attrs;
proxy_hide_header Set-Cookie;
proxy_set_header Authorization "";
proxy_intercept_errors on;
rewrite ^/app1/?$ /app1/index.html;
proxy_pass https://<s3 bucket name here>;
break;
}
}
So there is a corresponding bucket folder /app1 in s3 which has the dist contents and is serving up the index.html. And on the ALB, there are two route paths. The first is /app1 which redirects to https:{port}//app1/ and then the second route path /app1/* which just forwards to the nginx reverse proxy container deployed via ECS Fargate.
This is not using cloudfront. The bucket is proxied internally on https and specific permissions are set on the bucket to be accessible w/in the given VPC.
The angular apps have specific modules, but the issue is since Im not saving any of this content in the container, I can't just do a try_files, or set an index to make this work, since all of this is proxied from s3 and the content is accessed differently.
I can access the app at with the given proxy configuration above, but for other paths, say when I navigate to the part of the apps where its /app1/account and then do a refresh, the page throws an access denied on the bucket and I just get the standard xml page in the browser.
How do I get this to work with all of those other relative paths without having to add each of those paths to nginx or the ALB routes? In other words, I dont want to have to add
location /app1/account {
}
and so on, or something like that. Yes, Im sort of new to nginx, so im still figuring things out.
I was expecting the above proxy to work with all paths on /app1 but im unsure what other route paths need to be added to the ALB or if the regex is off, or what else needs to be added to the nginx conf file.
All that to say, when I enter this
https://timemachine.com/app1
or this,
https://timemachine.com/app1/
both work and just rewrite to the index.html which is good.
After this, when I click on another icon in the UI that directs to another path on /app1/, I get directed to the page correctly at...
https://timemachine.com/app1/news
but then on a refresh on this path, instead of hitting url https://timemachine.com/app1/news, with all the data shown when I accessed this through UI, the url stays at https://timemachine.com/app1/news but the page defaults to s3 bucket access denied on that route(.xml).
The goal is just to be able to reload on the pages I can already access without the UI blowing up and defaulting to the access denied message. So I would like to be able to just enter https://timemachine.com/app1/news, which will display the content, then do a refresh and see the content again.
The are various modules within the angular apps and so these are relative paths, which may be part of the problem.
NOTE: All files, aside from assets folder, are in the base app1 bucket folder. So https://<s3_bucket_name>/app1 (with app1 being the folder).
Angular's docs indicate to use the Frontend Controller pattern for static files like so:
Use try_files, as described in Front Controller Pattern Web Apps,
modified to serve index.html:
try_files $uri $uri/ /index.html;
Obviously, that won't work here (since the files aren't local to nginx) so my understanding is we're looking for equivalent logic to that for when the files are hosted elsewhere.
Route not-assets to index.html
All assets are in the /assets/ folder - so the simplest solution is to look for anything starting with not-that and proxy those requests to the html file for the response:
server {
location ~ /app1/ {
rewrite ^/app1/(?!assets/) /index.html;
proxy_pass https://domain/bucket/app1/;
}
}
That regex means that:
/app1/assets/some.css gets proxied to https://domain/bucket/app1/assets/some.css
/app1/ gets proxied to https://domain/bucket/app1/index.html
/app1/something/else gets proxied to https://domain/bucket/app1/index.html
etc.
Do note that this is going to make your app respond HTTP 200 OK with html to almost any url - which may be confusing.
If there are any problems setting this up, enable the nginx debug log to see to what url requests are being proxied, and determine the difference from what's desired.

Nuxt.js app behind nginx reverse-proxy loading multiple pages at once

I've a nuxt.js app behind nginx reverse proxy. The nginx conf file looks like this:
server {
listen 80;
# Match *.lvh.me
server_name ~^(?<user>.+)\.lvh\.me$;
location / {
proxy_pass http://localhost:8080/sites/$user$uri$is_args$args;
}
location ~* \.(?:js|css|jpg|jpeg|gif|png|ico|cur|svg)$ {
proxy_pass http://localhost:8080;
}
}
As you can see I'm mapping all my site subdomains to a specific path on my site and it is working fine. I'm also mapping all assets to be loaded from the root (because otherwise it throws a 404 error).
The only issue I'm facing is the whenever I visit a subdomain e.g subdomain.lvh.me it loads two pages on top of each other, the original page from subdomain root (which is expected) but also the page from the main domain root i.e. lvh.me (which is not expected).
Can you please checkout my conf file to see if I'm doing anything wrong here?
So I've encountered this issue and what I did to fix it was to not rely on Nginx's root nor proxy_pass. Instead, I used a location block with an alias and a try_files inside like so:
location ^~ / {
alias /path/to/dist;
try_files $uri $uri/ /index.html = 404;
}

Nginx reverse proxy didnt load site correctly

I have an nginx configuration which listens to any subdomain *.mydomain.com,
and I want to use subdomain as variable, to proxy request to other site.
Here is my nginx configuration
server {
listen 80;
server_name "~^(?<subdomain>.*).mydomain.com";
location / {
resolver 1.1.1.1 1.0.0.1 ipv6=off;
proxy_pass http://hosting.mydomain.com/$subdomain/;
proxy_redirect off;
access_log /var/log/nginx/proxy.log;
}
}
As I request the site directly and it loads perfectly
Site placed on AWS S3, and bucket static website address cnamed to mydomain
However, when I try to access via user1.mydomain.com, the page didn't load images, and css
This is the same site
And in browser network panel shows
Difference between direct and proxy access
This issue is made, because I have many sites stored in S3 bucket and located in different folders (the folder name is used as subdomain).
And I want to use a single domain to access all of them via subdomains.
Thanks in advance
You forgot to proxy pass the URI, you're serving user1/index.html for every request, including for JS and CSS requests, it's why all of responses are the same size (2kb, the size of user1/index.html), and it's also why you're getting Uncaught SyntaxError: Unexpected token < in the first line of Enterprise_skeleton.bundle.js because it's returning an HTML document that starts with <!doctype html> instead of the actual JS bundle.
Change
location / {
proxy_pass http://hosting.mydomain.com/$subdomain/;
}
to
location / {
proxy_pass http://hosting.mydomain.com/$subdomain$uri;
}

nginx different authentication for different directories

finding alternative of htaccess in apache for nginx, want to add different authentication rules for different directories. Different .htpasswd files for different directories. how to do it? Just like bitbucket does, it runs on nginx too.
I'm pretty sure that the authentication within BitBucket is handled by the application, there's no .htpasswd files anywhere to be found, authentication isn't handled by the web server.
However you can configure nginx to use a different .htpasswd for different paths using different location blocks for each path
location / {
root /var/www/app/;
index index.html index.php;
auth_basic_user_file /var/www/app/.htpasswd;
}
location /pathA {
root /var/www/app/pathA;
index index.html index.php;
auth_basic_user_file /var/www/app/pathA/.htpasswd;
}
or something to that effect

Apache + NginX reverse proxy: serving static and proxy files within nested URLs

I have Apache running on my server on port 8080 with NginX running as a reserve proxy on port 80. I am attempting to get NginX to serve static HTML files for specific URLs. I am struggling to write the NginX configuration that does this. I have conflicting directives as my URLs are nested within each other.
Here's what I want to have:
One URL is at /example/ and I want NginX to serve a static HTML file located on my server at /path/to/www/example-content.html instead of letting Apache serve the page to NginX.
Another URL is at /example/images/ and I want Apache to serve that page to NginX, just as it does for the rest of the site.
I have set up my nginx.conf file like this:
server {
listen 80;
server_name localhost;
# etc...
location / {
proxy_pass http://127.0.0.1:8080/;
}
# etc...
My attempt to serve the static file at /example/ from NginX went like this:
location /example/ {
alias /path/to/www/;
index example-content.html;
}
This works, but it means everything after the /example/ URL (such as /example/images/) is aliased to that local path also.
I would like to use regex instead but I've not found a way to serve up the file specifically, only the folder. What I want to be able to say is something like this:
location ~ ^/example/$ {
alias /path/to/www/example-content.html;
}
This specifically matches the /example/ folder, but using a filename like that is invalid syntax. Using the explicit location = /example/ in any case doesn't work either.
If I write this:
location ~ ^/example/$ {
alias /path/to/www/;
index example-content.html;
}
location ~ /example/(.+) {
alias /path/to/www/$1;
}
The second directive attempts to undo the damage of the first directive, but it ends up overriding the first directive and it fails to serve up the static file.
So I'm at a bit of a loss. Any advice at all extremely welcome! Many thanks.
Since you say you have Apache running, I assume it is there to run dynamic content such as PHP (Otherwise it is not needed). In that case, the example config below will serve all static content with Nginx and pass others to Apache.
server {
# default index should be defined once as high up the tree as possible
# only override lower down if absolutely required
index index.html index.php
# default root should be defined once as high up the tree as possible
# only override lower down if absolutely required
root /path/to/www/
location / {
try_files $uri $uri/ #proxy;
}
location #proxy {
proxy_pass http://127.0.0.1:8080;
# Other Proxy Params
}
location ~ \.php$ {
error_page 418 = #proxy
location ~ \..*/.*\.php$ { return 400; }
return 418;
}
}
What this assumes is that you are following a structured setup where the default file in every folder is either called "index.html" or "index.php" such as "/example/index.html", "some-folder/index.html" and "/some-other-folder/index.html".
With this, navigating to "/example/", "/some-folder/" or "/some-other-folder/" will just work with no further action.
If each folder has default files with random different names, such as "/example/example-content.html", "some-folder/some-folder.html" and "some-other-folder/yet-another-different-default.html", then it becomes a bit more difficult as you then need to do something like
server {
# default index should be defined once as high up the tree as possible
# only override lower down if absolutely required
index index.html index.php
# default root should be defined once as high up the tree as possible
# only override lower down if absolutely required
root /path/to/www/
location / {
try_files $uri $uri/ #proxy;
}
location #proxy {
# Proxy params
proxy_pass http://127.0.0.1:8080;
}
location ~ .+\.php$ {
error_page 418 = #proxy
location ~ \..*/.*\.php$ { return 400; }
return 418;
}
location /example/ {
# Need to keep defining new index due to lack of structure
# No need for alias or new root
index example-content.html;
}
location /some-folder/ {
# Need to keep defining new index due to lack of structure
# No need for alias or new root
index some-folder.html;
}
location /some-other-folder/ {
# Need to keep defining new index due to lack of structure
# No need for alias or new root
index yet-another-different-default.html;
}
# Keep adding new location blocks for each folder
# Obviously not the most efficient arrangement
}
The better option is to have a structured and logical layout of files on the site instead of multiple differing locations.