Can't sent nginx basic auth on server with Strapi - nginx

I want to setup nginx basic auth for my server that contains Strapi (we are using this server to query it with GraphQL for static content) to prevent unauthorised visitors while product is in development.
Strapi is located on port 1337, so I can access it via 127.0.0.1:1337 and see here starting page of Strapi that has button to redirect forward to the admin portal login (127.0.0.1:1337/admin that afterwards redirects to 127.0.0.1:1337/admin/auth/login).
If I'm adding basic auth in nginx (successfuly added it on other servers for the project), it works for the first page on root domain, but after going to /admin to the admin panel I spotted 2 different behaviours (depending on the browser)
Chrome constantly asks for basic auth on /admin and refreshes after every input, it's simply not letting me further
Safari bypasses the basic auth prompt, but when I try to login in /admin it just refreshes without any errors and not letting me further.
P.S. I'm not a DevOps guy, I'm project manager but currently our project is not having dedicated DevOps person to solve issues like that, so have to do everything by myself. Don't blame for dooing something wrong here :)
This is how I tried setting up nginx, all I did is generated the .httpasswd file with login and pass and added following code to the /etc/nginx/sites-available/default
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
#try_files $uri $uri/ =404;
proxy_pass http://localhost:1337;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $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-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass_request_headers on;
auth_basic "Login here!";
auth_basic_user_file /etc/nginx/.htpasswd;
}
header parameters taken from here https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/deployment/optional-software/nginx-proxy.html#nginx-virtual-host
Also tried same configuration as works on other server that had NextJS app running under basic auth
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
#try_files $uri $uri/ =404;
proxy_pass http://localhost:1337;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
auth_basic "Login here!";
auth_basic_user_file /etc/nginx/.htpasswd;
}
Both now working, any ideas why?

Related

Custom nginx auth header - without Authorization

I have a proxied nuxt app set up like this:
location / {
proxy_pass http://localhost:3011/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $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;
}
This works great. Now I want to restrict it for development purposes so only my team have access to it.
I cannot use IPs because some team members have dynamic IP. So I stumbled upon auth_basic and set it up by adding:
auth_basic "Restricted";
auth_basic_user_file /etc/apache2/.htpasswd;
This also works fine as far as restriction goes. The problem is that it uses the Authorization header and that interferes with our app's authentication mechanism.
Is there any way to make nginx use another header like maybe X-Authorization?
If your app has authentication mechanism , its better to control access from there among teams.
Pretty sure http_basic_auth works on standards. https://www.rfc-editor.org/rfc/rfc7235#section-4.2.
RFC7234, section 3.2 says that requests/responses Authorization header MUST not be cached (except in specific circumstances).
RFC7235, section 5.1.2, point 7 furthermore has this say to about NEW authentication schemes that use headers other than Authorization:
If you want auth on some specific paths, then
location /public/setup-steps {
auth_basic "Restricted";
auth_basic_user_file /etc/apache2/.htpasswd;
proxy_pass http://localhost:3011/;
}
Just remember to put this location before /.

How to setup a Nginx reverse proxy for an ASP.NET app URL

I have an ASP.NET based app (on IIS8); which loads perfectly when visiting it directly at: http://localhost:89/files
When I visit my ngnix reverse proxy URL: http://localhost/files, instead of loading the webpage, the file Login.aspx is downloaded by the web browser. I don't have any issues with reverse proxying the root domain (for regular HTML webpages).
I would like to resolve this issue without modifying my ASP.NET app if at all possible. Below, is the configuration I'm using in nginx.conf:
server {
listen 80;
server_name localhost;
location / {
root "C:\inetpub\wwwroot";
index index.html index.htm;
}
location /files {
proxy_pass http://localhost:89/files/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Maybe, there's something I need to change on my Web.config file for the ASP.NET app?

NGINX internal redirect from uri path to JSF context root

I'm configuring a cloud server which use NGINX as reverse proxy to serve different applications on different URI (all the applications are on the same wildfly standalone instance).
To be more specific i've a JSF application with a contextroot, let's say, /jsfcontext and i've set up a NGINX location like /mypublicuri.
What happens is that when I navigate to https://myserver.com/mypublicuri/index.xhtml i receive the following error:
/mypublicuri/index.xhtml Not Found in ExternalContext as a Resource.
I'm pretty sure it's related to a missing internal redirect route or some kind of "hack" that i need to specify in order to make everything work but i'm a newbie in NGINX and I don't know how to properly set everything up.
Thanks for the help
Cheers
Read NGINX documentation but my lack of english knowledge makes difficoult to understand what should I have to do
My actual NGINX config
server {
server_name myserver.com www.myserver.com;
access_log /usr/share/logs/access.log;
error_log /usr/share/logs/error.log;
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_intercept_errors on;
location /anotherworkingapp {
add_header Allow "GET, POST, HEAD, PUT, DELETE" always;
proxy_pass http://127.0.0.1:8080$request_uri;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location /mypublicuri {
proxy_pass http://127.0.0.1:8080/jsfcontext$request_uri;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
}

Accessing WSO2-APIM using Nginx

I am accessing my wso2 apim,store and publisher using Nginx.
and want to access using the following:
wso2 api manager to be accessed using nginx url as:
https://nginx-ip/wso2am/carbon
wso2 store to be accessed using nginx url as:
https://nginx-ip/wso2am/store
wso2 store to be accessed using nginx url as:
https://nginx-ip/wso2am/publisher
I tried using nested location block inside location block but wasn't successful.
So, now I am working by having a location block for all of them separately but the same also doesn't works.
Here is my nginx configuration file for store:
location /wso2am/store/
{
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://wso2-ip:9443/store/;
proxy_redirect https://$http_host/store/ /wso2am/store/;
proxy_cookie_path / /wso2am/;
limit_rate 25M;
#limit_req zone=wso2am burst=100 nodelay;
}
For the above configuration the GUI for store doesn't appears properly.
Similarly for publisher and carbon(for apim management console).
And the nested nginx configuration is as follows:
location /wso2am/ {
location /wso2am/store/
{
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://wso2-ip:9443/store/;
proxy_redirect https://$http_host/oauth2/callback /oauth2/callback;
proxy_redirect https://$http_host/ /wso2am/store/;
proxy_redirect https://$http_host/wso2am/ /wso2am/store/;
proxy_redirect https://$http_host/store/ /wso2am/store/;
proxy_cookie_path / /wso2am/;
limit_rate 25M;
}
}
Where do I have to change in headers or any other location to go correct?
Update 1:
My wso2am store and publisher are working after incorporating the comments and using the following nginx conf:
location /wso2am/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://wso2-apim-ip:9443/;
proxy_redirect https://$http_host/carbon/ /wso2am/carbon/;
proxy_redirect https://$http_host/store/ /wso2am/store/;
proxy_redirect https://$http_host/publisher/ /wso2am/publisher/;
proxy_cookie_path / /wso2am/;
}
Note: But using the above configuration,I login to apim-carbon,I get logged in and then if I click on any of the options on the home page such as list,add.I get logged out and the reason behind it after investigation was the CSRF token is not being sent in the request while accessing it using Nginx.
How can the csrfprevention.js issue be resolved keeping it true.?
Disclamer: this is an incomplete answer, for I am myself digging into this question
I faced the very same issue with both wso2am and wso2ei. I am pretty sure that we need to edit /repository/conf/carbon.xml in this section (I must admit that the comments are not crystal clear):
<!--
Webapp context root of WSO2 Carbon management console.
-->
<WebContextRoot>/wso2am</WebContextRoot>
<!--
Proxy context path is a useful parameter to add a proxy path when a Carbon server is fronted by reverse proxy. In addition
to the proxy host and proxy port this parameter allows you add a path component to external URLs. e.g.
URL of the Carbon server -> https://10.100.1.1:9443/carbon
URL of the reverse proxy -> https://prod.abc.com/appserver/carbon
appserver - proxy context path. This specially required whenever you are generating URLs to displace in
Carbon UI components.
-->
<MgtProxyContextPath>/</MgtProxyContextPath>
<ProxyContextPath>/wso2am</ProxyContextPath>
The following works if your Nginx listen to 443 in SSL mode (couldn't do it with HTTP because of the redirections -> make a self signed certificate if you plan to use it on a local network)
location /wso2am {
proxy_pass https://wso2_apimanager_container:9443;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_ssl_verify off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /wso2am/store {
proxy_pass https://wso2_apimanager:9443/store;
}
location /wso2am/publisher {
proxy_pass https://wso2_apimanager:9443/publisher;
}
location /wso2am/admin {
proxy_pass https://wso2_apimanager:9443/admin;
}
}
It works but I am not completely sure why. Can someone explain to me in which aspect <MgtProxyContextPath> differs from </MgtProxyContextPath> and from <WebContextRoot>?
allow proxy for admin publisher and store: to make /publisher, /store and /admin accessible, you need to edit the end of their respective site.json located in /repository/deployment/server/jaggeryapps/name_of_the_service/site/conf/site.json . For /publisher, you would write:
"reverseProxy" : {
"enabled" : "auto", // values true , false , "auto" - will look for X-Forwarded-* headers
"host" : "some.ip.or.domain", // If reverse proxy do not have a domain name use IP
"context":"/wso2am/publisher",
//"regContext":"" // Use only if different path is used for registry
},
Still have issue with the login though
You can follow this guide [1] to configure WSO2 API Manager with Nginx.
[1] -
https://docs.wso2.com/display/AM260/Configuring+the+Proxy+Server+and+the+Load+Balancer

Proxy_pass to url NGINX with a Meteor Server

I have configured a meteor server and setup the nginx configuration. The route works however when configuring dynamic subdomains to point to a specific part of the web app it produces a 404 error on the browser when loading the meteor file.
I am attempting to direct all *.domain.com to http://localhost:3000/booking/
My configuration is:
server {
server_name *.domain.com;
listen 80;
location / {
proxy_pass http://localhost:3000/booking/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; #for websockets
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}
The 404 occurs in the Meteor JS file.
If I remove the above nginx subdomain configuration and go to a subdomain it works perfectly, loading the route application. I assume I am missing something to load the application correctly.
The issue only occurs when I proxy_pass to a route within the URL <url>/booking
There are different ways of solving the issue.
1 - In case of 404 try a fallback option without booking in url
server {
server_name *.domain.com;
listen 80;
location / {
proxy_pass http://localhost:3000/booking/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; #for websockets
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
error_page 404 = #fallback;
}
location #fallback {
proxy_pass http://localhost:3000/$request_uri;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; #for websockets
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}
2 - Have a separate block for js and css
server {
server_name *.domain.com;
listen 80;
location / {
proxy_pass http://localhost:3000/booking/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; #for websockets
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
location ~ \.(js|css|font)$ {
proxy_pass http://localhost:3000/$request_uri;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}
I have a similar setup, where I have configured different Meteor applications on several subdomains plus a static website on the domain root, all pointing interlly to different ports.
Here is my setup step by step.
Folder structure, location and proxy pass
First thing to think about is the folder strucutre. Depending on your subdomain's VHost-root directory there is a relative path to your subdomain's application folder.
Imagine the following setup:
/www (dir, usually under /var)
/domain (dir)
/websitexy (dir, a static website is deployed under this dir)
/subdomain (dir)
/books (dir, subdomain app is deployed under this dir)
For such a setup I made my nginx config to point to the app's location within the subdomain:
location /books {
I had a similar issue when first time starting my app. One thing I found out is, that my config worked, when setting proxy_pass on my private ip/port combination:
proxy_pass http://172.x.x.x:3000;
This also involves to remove the route name (/books) adter the port number on this entry. Now your proxy pass involves all routing within your subdomain.
Note on routing
Note, that there can be confusion about routing here. By setting the location property you set the routing on the nginx level (server's directory structure), which is why there is no route within your proxy pass.
Your application may have it's own internal routing defined. It is important, that you app's internal router retrieves all requests based from it's application ur root. This is why it is important to have the proxy pass not to include any path after the port number.
Websocket
I have read some articles on nginx and websocket connections. Basically my initial settings came from this article and looked like from this documentation article:
location /app {
proxy_pass 172.x.x.x;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
I also had to add a proxy_read_timeout and proxy_send_timeout because there was an issue with the websocket protocol otherwise:
By default, the connection will be closed if the proxied server does
not transmit any data within 60 seconds. This timeout can be increased
with the proxy_read_timeout directive
So I also set the timeout values:
proxy_read_timeout 36000s;
proxy_send_timeout 36000s;
proxy_set_header Connection "upgrade";
Read more on this here and here.
Summarizing my setup looks like the following (using your app credentials):
location /books {
proxy_pass http://172.x.x.x:3000;
proxy_http_version 1.1;
proxy_read_timeout 36000s;
proxy_send_timeout 36000s;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
So to solve your case, you may check on your vhost directory (the one where your app is deployed, see folder structure above) and change your location and proxy_pass setting accordingly.
If this is not working, you may need to add some more output of your errors, e.g. a excerpt of the log when attempt to connect.

Resources