0

I am using Nginx to reverse proxy a handful of web servers with each being streamed which works really well, this is the config:

stream {
        map $ssl_preread_server_name $name {
                portal1.site.com portal1_backend;
                portal2.site.com portal1_backend;
                portal3.site.com portal1_backend;
                portal4.site.com portal1_backend;
        }

        upstream portal1_backend {
                server 10.1.1.1:443;
        }

        upstream portal2_backend {
                server 10.1.1.2:443;
        }

        upstream portal3_backend {
                server 10.1.1.3:443;
        }

        upstream portal4_backend {
                server 10.1.1.4:443;
        }
        server {
                listen 10.1.2.2:443;
                proxy_pass $name;
                ssl_preread on;
        }
http {
        server {
                listen 80;
                server_name portal1.site.com;

                location / {
                    return 301 https://$server_name$request_uri;
                }

                location /.well-known/ {
                        proxy_pass http://10.1.1.1:80;
                }  # do not redirect requests for iframe location
        }

        server {
                listen 80;
                server_name portal2.site.com;

                location / {
                        return 301 https://$server_name$request_uri;
                }

                location /.well-known/ {
                        proxy_pass http://10.1.1.2:80;
                }
        }

        server {
                listen 80;
                server_name portal3.site.com;

                location / {
                        return 301 https://$server_name$request_uri;
                }

                location /.well-known/ {
                        proxy_pass http://10.1.1.3:80;
                }
        }

        server {
                listen 80;
                server_name portal4.site.com;

                location / {
                        allow 1.2.3.4;
                        deny all;
                        return 301 https://$server_name$request_uri;
                }

                location /.well-known/ {
                        proxy_pass http://10.1.1.4:80;
                }
        }
}

Each has port 80 redirecting to https, except for the .well-know location for Lets Encrypt.

What I need to be able to do is limit what IP addresses are able to connect to the 4th server without impacting current functionality, and not restricting the other servers.

This config was put together referring to Nginx TCP forwarding based on hostname

Is this possible?

Iain
  • 1
  • 4

1 Answers1

0

I looked around for quite a while, and tried several different configuration variations, and had to settle on a work-around. Since the stream block is limited to having a single server block, whatever allow/deny statements you include there are "all or nothing".

The work-around I settled on (while not ideal) seems to be pretty functional and not too hard to automate/maintain with basic sync scripts.

My primary inbound proxy server is able to control access to private resources on port 80 of each local http server on a 'case by base', so it handles all the inbound 80 access control and filtering.

But if I need to limit access to a private resource encrypted tcp stream on port 443, I hand the stream off to a secondary nginx proxy server (that's only running a stream proxy server on 443), and do my additional filtering and access control there.

IPs are cheap in private land, and the latency is extremely minimal (<0.000). I do run both my nginx stream proxies "joined at the hip" via proxmox lxc containers, so they're practically on the same machine.

I suppose you could even daisy chain additional proxies, and get pretty elaborate with your filtering... But that may turn into a tangled web quickly if not thoughtfully planned out :)

(May even be able to run all stream servers on same VM/server/container, but different IPs. I didn't try that.)

  • Thanks for that, I never thought to do it that way, but without trying it, that looks a perfectly viable option. I'm not sure when I'll get to try it as on other projects at the moment, but will try soon. – Iain Oct 11 '22 at 06:37