path based routing as a reverse proxy - nginx

We were looking to use the AWS application load balancer (ALB) to direct incoming requests to specific servers where a "tenant" may reside. For example - customerA signs up to our free trial and we provision them a new instance of our application on webserver1 and we send them a link to their app, eg. https://trial.our.app/customerA
What we need is for our automated deployment that we will design and develop to ensure that when that person hits the load balancer it directs them to the appropriate server. However, from what we understand the AWS ALB has a rule limit of 100 rules therefore if we hit 100 free trials we would have run out of rules :
if path is '/customerA/*' then forward to webserver1
if path is '/customerB/*' then forward to webserver1
...
if path is '/customerX/*' then forward to webserver2
if path is '/customerY/*' then forward to webserver3
etc.
Also, if the customer browses to the "root" https://trial.our.app it redirects them to our website free trial page (different URL, eg. https://ourwebsite.io/freetrial)
We're not looking to load balance, it will simply be a case of redirecting the customer to their appropriate webserver where they have been provisioned.
We're considering NGINX (and are new to it!) and have spun it up to test this out and it mostly works, however we are unsure of a few things:
what would a basic/sample configuration of this look like? what he have so far on our test is as follows:
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
location = / {
return 301 https://ourwebsite.io/freetrial;
}
location /customerA {
proxy_pass http://10.101.1.149/;
}
location /customerB {
proxy_pass http://10.101.2.34/;
}
}
how do we ensure the location path is case insensitive, processes and includes everything after the path , eg. https://trial.our.app/customerA/#/app
how would you go about automating this so that the nginx config is updated when a new customer signs up and is added to the list of "locations" in the nginx.conf file?
any other suggestions of how best to approach this? are we using the right approach?

Related

One Next.js instance for two domains - how to redirect?

Let's say I have a business offering two different types of services. I would like to have two domains, eg. example-shop.com and example-rental.com and have one Next.js server instance for both of them (so that they can use common components, styles etc.). How should I configure Next.js or the server (eg. with Nginx) to make it work?
What I've tried:
In my Next.js project, I created the subfolders /pages/shop/ and /pages/rental/. I built the project and run it on the server on port 3000. Then, I set up an Nginx reverse proxy on my server with the following redirects:
server {
listen 80;
server_name example-shop.com;
location / {
proxy_pass http://localhost:3000/shop/;
}
}
server {
listen 80;
server_name example-rental.com;
location / {
proxy_pass http://localhost:3000/rental/;
}
}
The HTML file loads correctly, but all the other files (js, css, images) are also redirected to /shop or /rental and end up with 404. How can I fix this?
My ideas:
only redirect HTML files to localhost:3000/shop or localhost:3000/rental and redirect all the other requests to localhost:3000/ (but how?)
set up Next.js so that all the resource files are stored under a separate directory - then I could do
location /resources {
proxy_pass http://localhost:3000/;
}
... but how?

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.

Nginx reverse proxy - Internal servers separated by trailing slash

I'm a newbie at Nginx, and have been searching a lot for the right answer to my question, but couldn't find it; not because it is not there, but my newbie condition limits me to adapt a generic solution to my issue.
The situation is this:
I have a Mantis Bug Tracker in my private LAN (http://10.111.111.12).
On the other hand, i have an OwnCloud website also on my LAN (IP 10.111.111.5), with URL http://10.111.111.5/owncloud/.
What i want to do is to deploy a Nginx Reverse Proxy that handles all requests from Internet at publicdomain.com, and use trailing slash for each internal webserver. The desired result would be:
http://www.publicdomain.com/bugtracker -> redirects to http://10.111.111.12/index.php
http://www.publicdomain.com/cloud -> redirects to http://10.111.111.5/owncloud/ (note that "cloud" is preferred over "owncloud")
On the future, it is necessary to continue using trailing slash for other web servers to be deployed.
Questions are:
is this scenario possible? if so, is it enough with configuring nginx or I have to reconfigure internal web servers as well?
I really appreciate your help, by indicating me a possible solution or pointing me to the right direction on previous posts.
Thanks a lot in advance.
Yes it is possible to achieve such configuration and it's commonly used when NGINX is acting as a reverse proxy. You can use this configuration as an inspiration for building your own:
upstream bugtracker {
server 10.111.111.12;
}
upstream cloudupstream {
server 10.111.111.5;
}
server {
listen 80;
location /bugtracker/{
proxy_pass http://bugtracker;
}
location /cloud/{
proxy_pass http://cloudupstream/owncloud;
}
}
What's happening over here is that nginx will be listening on port 80 and as soon as a request comes for path /bugtracker, it will automatically route the request to the upstream server mentioned above. Using this you can add as many upstream servers and location blocks as you want.
Reference: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
Thanks a lot Namam for your quick answer. However, it isn't working yet. It seems that "server" at upstream directive does not allow slash, like this:
server 10.111.111.5/owncloud;
If i used it, i obtained
nginx: [emerg] invalid host in upstream "10.111.111.5/owncloud" in /etc/nginx/nginx.conf:43
I started with the first upstream bugtracker, only, and nginx.conf like this:
upstream bugtracker {
server 10.111.111.12;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name localhost;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
location /mstic{
proxy_pass http://bugtracker;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
After that, when accesing to my Nginx Reverse proxy http://10.111.111.10/mstic/ i obtain the following:
Not Found The requested URL /mstic/ was not found on this server.
and no further details on error or access logs.
Thanks a lot in advance for any extra help you could bring me.

Nginx reverse proxy configuration multi domains virtualhost

I'm having trouble configuring my nginx proxy despite reading a number of guides and trying for three consecutive evenings.
Here is my topology:
(From internet) All traffic from port 80 is redirected to 192.168.1.4, a ubuntu-server virtual running nginx.
I have a NAS which has a subdomain myName.surname.com which connects to the admin page. On that NAS, I have apache webserver running hosting a couple of sites on port 81, 82,
The NAS uses virtualhosts, so domains successfully redirect (without using nginx).
I also have an ASP.NET website running on IIS on another 192.168.1.3:9810.
Now here is my NGINX configuration. I tried configuring it a few times but broke it so I've put it back to its default state:
server {
listen 80 default_server;
root /usr/share/nginx/html;
index index.html index.htm;
server_name localhost;
location / {
proxy_pass http://192.168.1.1; #WORKS OK
}
}
If I go on myName.surname.com or wordpressWebsite.co.uk or myIISSiteDomain.co.uk I am with config above greeted with the correct page at 192.168.1.1:8080 OR 192.168.1.1:81.
It's a start.
First problem is When I navigate to any other page (not home page) like wordpressWebsite.co.uk/blog, it breaks giving 404. So I have tried to differentiate between URLs? I read that the config should be something like:
server {
listen 80;
server_name wordpressWebsite.co.uk;
location / {
proxy_pass http://192.168.1.1:81;
}
}
server {
listen 80;
server_name myName.surname.com;
location / {
proxy_pass http://192.168.1.1;
}
}
server {
listen 80 myIISSiteDomain.co.uk
location / {
proxy_pass http://192.168.1.3:9810;
}
}
But this is not quite right.
1) wordpressWebsite.co.uk loads up the page, but as soon as I go to any other link like wordpressWebsite.co.uk/blog it breaks, giving me my NAS error message like its trying to access 192.168.1.1/blog rather than the virtualhost ~/blog. It actually changes my URL in navbar to 192.168.1.1 so why is it behaving like this?
2) if I'm using virtual host, I don't think I should need to pass in the port via nginx for 192.168.1.1:81 (wordpressWebsite.co.uk). Surely I just need to point it to 192.168.1.1, and then virtualhost should detect that the url maps to 81? I'm not sure how to to do this as I don't fully understand what actually gets passed from nginx to the server?
You can add try_files $uri $uri/ /index.php?$args;
See this https://www.geekytuts.net/linux/ultimate-nginx-configuration-for-wordpress/

opening other websites links in nginx server

I am new to Nginx and I have set up the server using this tutorial. Now when I add links to other sites like http://www.anotherwebsite.com and when I click on this link from my page the server directs me to http://www.mywebsite.com/http://www.anotherwebsite.com. The server is appending the other link to my website link. How do I change that. I have looked into these places
How to redirect a url in NGINX,
Rewrite to pretty links with nginx
but I just cant make it work. Any help will be appreciated. Thanks
server {
listen 80;
server_name $hostname;
location /static {
alias /var/www/<app-name>/static;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/tmp/uwsgi.sock;
uwsgi_param UWSGI_PYHOME /var/www/<app-name>/env;
uwsgi_param UWSGI_CHDIR /var/www/<app-name>/project;
uwsgi_param UWSGI_MODULE <project-name>.wsgi:application;
}
}
you're not doing any redirecting at all from your posted nginx config,
everything except /static/ and /50x.html is passed on to the uwsgi app
consequently the redirecting has to be happening in the uwsgi app
As far as redirecting from within nginx goes, the simple case goes like this:
location /redirected-path {
#for 302 redirect
rewrite ^ http://anotherwebsite.example.com/path-on-other-site redirect;
#for 301 redirect
# rewrite ^ http://anotherwebsite.example.com/path-on-other-site permanent;
}
(the more complicated cases involve regexes more complicated then ^)
UPDATE:
right, so from the code you linked in the comment below, what you really want to do is change the href value of the outputted html code anchor tag.
The proper place to do so is in the backend code (i.e. in the uwsgi app you're connecting to)
You could do it with the following rewrite:
location /main {
rewrite ^/main(.*) http://www.mysite.com$1 permanent;
}
BUT this has the big drawback of requiring an extra roundtrip to the server, a client then does:
request to your server
response with redirect to the other server
request to the other server
response from the other server
whereas if you change it in the backend code steps 1 and 2 are no longer needed.
Besides causing a potentially (depending on connection speed and server load) noticable delay. It will also increases your server load.
Doing it with a server-rewrite is a hack you really should skip unless you have no access to the backend code

Resources