nginx: subdomains, map to 2nd host with multiple ports - nginx-reverse-proxy

I have been looking for an nginx reverse proxy config that can:
receive incoming traffic from my router on port 80, from mydomain.com;
from subdomains, say sd01, sd02, sd03.
i.e. sd01.mydomain.com - then must go via the nginx reverse proxy (host1), and point the request to host2 (all RPi's) behind my router, and be routed to a different port on this host2.
On host2 (ip address say 192.168.1.33), I have docker running several instances of node-red, each container pointing to a different port on host2:
- sd01.mydomain.com to point to 192.168.1.33:1101
- sd02.mydomain.com to point to 192.168.1.33:1102
- sd03.mydomain.com to point to 192.168.1.33:1103
I have seen so many options of doing this on the web, from using
map $subdomain $subdomain_port {
to others, but I cannot get it working. Could someone point me in the right direction please?
And yes, I have added the wildcard * directive on godaddy for the sub domains to point to the fixed ip of my router.

You should use the upstream directive in association with a proxy_pass in the location directive for this.
ie.
upstream sd01 {
server 192.168.1.33:1101;
}
upstream sd02 {
server 192.168.1.33:1102;
}
upstream sd03 {
server 192.168.1.33:1103;
}
server {
listen 80;
listen [::]:80;
root /var/www;
server_name sd01.mydomain.com;
location / {
proxy_pass http://sd01/;
}
}
server {
listen 80;
listen [::]:80;
root /var/www;
server_name sd02.mydomain.com;
location / {
proxy_pass http://sd02/;
}
}
server {
listen 80;
listen [::]:80;
root /var/www;
server_name sd03.mydomain.com;
location / {
proxy_pass http://sd03/;
}
}
Note that if you are using sockets you will need to upgrade the connection for that path:
location /socket/ {
proxy_pass http://socketserverupstream;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
}
This is a similar configuration that I use for all of my servers. You can however refer to the NGINX documentation.

In your nginx configuration file(nginx.conf) do these changes:
server
{
listen 80;
server_name sd01;
location / {
proxy_pass http://127.0.0.1:1101;
}
}
server
{
listen 80;
server_name sd02;
location / {
proxy_pass http://127.0.0.1:1102;
}
}

Related

How to configure Websocket secure (wss) on a Nginx node server?

I tried to configure a Websocket proxy on my Nginx server, but unfortunately, I don't get it working. I have read various forms but cannot get out of it. I think it has something to do between the client connection to the server. Local om my pc is everything working fine
client code:
var port = new osc.WebSocketPort({
url: "wss://circusfamilyprojects.nl/"
});
server code:
var wss = new WebSocket.Server({
port: 8083
});
This is my configuration in Nginx
# custom code for hop by hop headers
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
#custom code for connection with websocket this is the port on the server
upstream websocket {
server 178.62.209.37:8083;
}
server {
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/circusfamilyprojects.nl/fullchain.pem; # managed by Cert$
ssl_certificate_key /etc/letsencrypt/live/circusfamilyprojects.nl/privkey.pem; # managed by Ce$
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
root /var/www/html/vue/cfdomotica/server/public;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name circusfamilyprojects.nl www.circusfmailyprojects.nl; # managed by Certbot
location / {
proxy_pass http://websocket;
proxy_set_header HOST $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_pass_request_headers on;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
server {
if ($host = www.circusfamilyprojects.nl) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = circusfamilyprojects.nl) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 8080 ;
listen [::]:8080 ;
server_name circusfamilyprojects.nl;
return 404; # managed by Certbot
}
In my browser I get the message "Status Code: 426 Upgrade Required" I hope someone can help me, thanks in advance!
I solved it my self by separating a server block for port 443 and a server block for the WebSocket client. I did the server block for the client on port 8086.

why do I have a error 404 with nginx reverse proxy?

I am trying to reverse proxy my muximux and sonarr apps
I started with a simple conf :
server {
listen 80;
listen [::]:80;
server_name media.mydomain.com;
location / {
# reverse to muximux
proxy_pass http://localhost:8010/;
}
location /sonarr {
# reverse to sonar
proxy_pass http://localhost:8989/;
}
}
It is working for muximux but for sonar I have an error 404 but the url seems to be correct http://media.mydomain.com/login?returnUrl=
So what am I doing wrong ?

Nginx keeps redirecting infinitely

I've followed the instructions from here on setting up nginx to redirect all non-www requests into www but I keep getting ERR_TOO_MANY_REDIRECTS in my browser when I try to hit any page.
My goal is twofold:
All requests that don't have www should be redirected to www
All requests that aren't HTTPS should be redirected to HTTPS
My nginx config looks like this:
upstream mywebsite_proxy {
server unix:/home/deploy/mywebsite/tmp/sockets/puma.sock;
}
server {
listen 80;
listen [::]:80;
listen 443 default_server ssl;
server_name www.mywebsite.com;
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
location / {
proxy_pass http://mywebsite_proxy;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~ ^/(robots.txt|sitemap.xml.gz)/ {
root /home/deploy/mywebsite/public;
}
}
Notice that there isn't any reference to SSL certificates. I'm using Cloudflare with SSL enabled and HTTPS seemed to just work right out the gate when my config looked like the one below. The non-www to www and non http to https redirects obviously didn't work though...
upstream mywebsite_proxy {
server unix:/home/deploy/mywebsite/tmp/sockets/puma.sock;
}
server {
listen 80;
listen 443;
server_name www.mywebsite.com mywebsite.com;
root /home/deploy/mywebsite/public;
location / {
proxy_pass http://mywebsite_proxy;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~ ^/(robots.txt|sitemap.xml.gz)/ {
root /home/deploy/mywebsite/public;
}
}
In my opinion you do not need the if part in:
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
The redirect should look like this:
return 301 https://$server_name$request_uri;
Use 301 if you want to do a permanent redirect, which will be stored in the cache of your browser or 302 if you do not want it to be permanent. Furthermore, you can remove the www. part in the server_name and use return 301 https://www.$server_name$request_uri;
I did some thing similar in one of my previous project, here are the steps:
Left default config 'nginx.conf' as it is.
modified /etc/nginx/sites-available/default
(Gist: https://gist.github.com/faizulhaque-tp/db576dc6f22c820a0e23f7a6e1c8b740)
Apart from non-www to www, above configuration works.

Cannot activate HTTPS links with Django and Nginx

I have a django rest framework app running on a secured Nginx server.
When I navigate on the DRF api, the protocol in the navigation bar is well redirected to https.
My problem is that all the generated urls are in http instead of https.
I watched in the code, the differents url are build with this method:
def build_absolute_uri(self, location=None):
"""
Build an absolute URI from the location and the variables available in
this request. If no ``location`` is specified, bulid the absolute URI
using request.get_full_path(). If the location is absolute, convert it
to an RFC 3987 compliant URI and return it. If location is relative or
is scheme-relative (i.e., ``//example.com/``), urljoin() it to a base
URL constructed from the request variables.
"""
if location is None:
# Make it an absolute url (but schemeless and domainless) for the
# edge case that the path starts with '//'.
location = '//%s' % self.get_full_path()
bits = urlsplit(location)
if not (bits.scheme and bits.netloc):
current_uri = '{scheme}://{host}{path}'.format(scheme=self.scheme,
host=self.get_host(),
path=self.path)
# Join the constructed URL with the provided location, which will
# allow the provided ``location`` to apply query strings to the
# base path as well as override the host, if it begins with //
location = urljoin(current_uri, location)
return iri_to_uri(location)
In my case, this method always returns unsecured urls (HTTP instead of HTTPS).
I have edited my settings like it's described in this post:
https://security.stackexchange.com/questions/8964/trying-to-make-a-django-based-site-use-https-only-not-sure-if-its-secure
But the generated url are still in HTTP.
Here is my Nginx configuration:
server {
listen 80;
listen [::]:80;
server_name backend.domaine.na.me www.backend.domaine.na.me server_ip:8800;
return 301 https://$server_name$request_uri;
}
server {
# SSL configuration
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/ssl-backend.domaine.na.me.conf;
include snippets/ssl-params.conf;
location / {
proxy_pass http://server_ip:8800/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
proxy_redirect off;
}
}
server {
listen 8800;
server_name server_ip;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /projects/my_django_app;
}
location /media/ {
root /projects/my_django_app;
}
location / {
include proxy_params;
proxy_pass http://unix:/projects/my_django_app.sock;
}
location ~ /.well-known {
allow all;
}
}
And my django configuration:
In wsgi.py:
os.environ['HTTPS'] = "on"
os.environ['wsgi.url_scheme'] = "https"
In settings.py(Note: I've tried both first two lines):
#SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_PROXY_SSL_HEADER = ('HTTP_X_SCHEME', 'https')
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
I really need to fix this probem because my DRF api returns some image URL wich must be in HTTPS, else the site cannot be considered 100% secure.
What is wrong with my configuration? Am I missing some options?
The indirection isn't needed; you can merge the settings from the SSL block and the :8800 block to give something like this:
server {
listen 80;
listen [::]:80;
server_name backend.domaine.na.me www.backend.domaine.na.me;
return 301 https://$server_name$request_uri;
}
server {
# SSL configuration
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/ssl-backend.domaine.na.me.conf;
include snippets/ssl-params.conf;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /projects/my_django_app;
}
location /media/ {
root /projects/my_django_app;
}
location ~ /.well-known {
allow all;
}
location / {
proxy_pass http://unix:/projects/my_django_app.sock;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
proxy_redirect off;
}
}
Then, set SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') and it should work.
I can't find anything about include proxy_params, and I suspect that the headers that you set in the first proxy block aren't forwarded to the Django app at all.

nginx - browser can't stop directing to https?

Why nginx keep on directing without instructions?
I followed this guide to redirect port 80 to 3000:
server {
listen 80;
server_name example.co.uk www.example.co.uk;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:3000;
}
}
It worked fine. Then I tried to roll back as before, and it just keeps on redirecting to https!
I even have removed nginx, but the browser is still redirecting to https! Why? What have done wrong? How can I fix it?
Any ideas?
This was the config before I tried on the redirect thingy:
server {
listen 80;
server_name example.co.uk www.example.co.uk;
return 301 https://$host$request_uri;
}
server {
# listen 80;
listen 433 ssl;
server_name example.co.uk www.example.co.uk;
ssl on;
ssl_certificate /etc/letsencrypt/live/example.co.uk/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.co.uk/privkey.pem;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ~ /.well-known {
allow all;
}
the HTTPS was working fine to before that.
EDIT:
I have re-installed nginx and tested it with nginx -t:
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful