Reverse Proxy for hosting multiple servers behind single IP address

I have just purchased another domain for use with my private server that will be hosting various things such as WireGuard, SAMBA shares and Docker containers running Nextcloud, Pi-Hole, Plex etc. Additionally, I have a second physical server that my webserver stack sits on and is also using Docker containers. Both physical servers are configured in their own respective VLAN/DMZ for complete separation.

The biggest problem I have here with both servers is that a lot of the services use port 80 and/or 443 so I will need to utilise a reverse proxy on each server to handle the services. To add to the problem I only have one WAN IP address, so trying to reach the two reverse proxies on each physical server from the outside world will be difficult with various different port mappings. However, correct me if I'm wrong, by utilising a third reverse proxy in front of the two reverse proxies on each physical server I should be able to reach both servers?

As shown in the diagram below OpenWrt will listen on ports 80 and 443 (normal HTTP/HTTP(S) traffic and depending on what URL is being accessed from the internet, traffic will redirect to the reverse proxy on one of the servers themselves. Of course on each respective server the reverse proxies will be looking to see what subdomains are being accessed and passing these onto the correct service.

I currently have uHTTPd installed on OpenWrt and and I have already configured it to listen on ports other than 80/443. However, I'm debating on what reverse proxy to use. Squid seems lightweight but I'm not that confident with configuring it and documentation and some guides are limited and outdated. On the other hand, NGINX is very documented, there are tonnes of guides detailing how to setup a reverse proxy and there are plenty of people on forums who can help with it.

Where I'm getting a little lost is firstly, where I should enable SSL and secondly trying to get my head around how the NGINX package works on OpenWrt.

With the SSL, do I enable encryption on the first reverse proxy on my OpenWrt router, on the server reverse proxies themselves or can I enable SSL on all three reverse proxies and enable encryption right through from end to end? I'm planning to utilising Certbot or ACME for deploying Let's Encrypt certificates automatically as they work with Apache, NGINX and pretty much any of the major Linux distributions.

In regard to the OpenWrt NGINX package, can I simply install the package nginx-ssl as shown in the screenshot below and this will run alongside uHTTPd without any issues?

I have noticed that a symbolic link gets created at /etc/nginx/uci.conf, a UCI config file at /etc/config/nginx and some certificates in the conf.d directory. I've read through the NGINX on the OpenWrt Wiki here and the UCI configuration can be disabled with

uci set nginx.global.uci_enable=false

From experience with NGINX in a full-fletched Linux distribution such as Debian/Ubuntu whereby there is a /etc/nginx/nginx.conf file and two directories, /sites-available and sites-enabled with the latter defined using the include parameter in the configuration file. However, on OpenWrt I have the file /etc/nginx/uci.conf with a symbolic link to /var/lib/nginx/uci.conf and a comment section at the top of this file says it's re-created when NGINX starts.

/etc/nginx/uci.conf

# This file is re-created when Nginx starts. 
# Consider using UCI or creating files in /etc/nginx/conf.d/ for configuration. 
# Parsing UCI configuration is skipped if uci set nginx.global.uci_enable=false 
# For details see: https://openwrt.org/docs/guide-user/services/webserver/nginx 
worker_processes auto; 
user root; 
events {} 
http { 
        access_log off; 
        log_format openwrt 
                '$request_method $scheme://$host$request_uri => $status' 
                ' (${body_bytes_sent}B in ${request_time}s) <- $http_referer'; 
        include mime.types; 
        default_type application/octet-stream; 
        sendfile on; 
        client_max_body_size 128M; 
        large_client_header_buffers 2 1k; 
        gzip on; 
        gzip_vary on; 
        gzip_proxied any; 
        root /www; 
        server { #see uci show 'nginx._lan' 
                listen 443 ssl default_server; 
                listen [::]:443 ssl default_server; 
                server_name _lan; 
                include restrict_locally; 
                include conf.d/*.locations; 
                ssl_certificate /etc/nginx/conf.d/_lan.crt; 
                ssl_certificate_key /etc/nginx/conf.d/_lan.key; 
                ssl_session_cache shared:SSL:32k; 
                ssl_session_timeout 64m; 
                access_log off; # logd openwrt; 
        } 
        server { #see uci show 'nginx._redirect2ssl' 
                listen 80; 
                listen [::]:80; 
                server_name _redirect2ssl; 
                return 302 https://$host$request_uri; 
        } 
        include conf.d/*.conf; 
}

My question is, where is the main configuration file for NGINX if the /etc/nginx/uci.conf is recreated each startup? I'm happy configuring NGINX via CLI but I don't need any of the UCI related features therefore I would rather have a NGINX configuration file based at /etc/nginx I can configure manually. Is it possible to compile my own NGINX for OpenWrt that is similar to running NGINX on Debian/Ubuntu for example? If not, is there a way I can configure my own /etc/nginx/nginx.conf file for example without any UCI or startup scripts getting in the way?

/etc/nginx/nginx.conf

...
server { 
	listen 80; 
	server_name example.com; 
	return 301 https://$host$request_uri; 
} 
server { 
	listen 443 ssl; 
	server_name operwrt-ap1.lan; 
	location /some/path/ { 
		proxy_set_header Host $host; 
		proxy_set_header X-Real-IP $remote_addr; 
		proxy_pass http://localhost:60443; 
	} 
}
...

Some documentation and guides I've been reading

Once I've got this working, I will be eventually creating a guide on the Wiki so others can benefit🙂

Hello,

I am currently running HAProxy on my OpenWRT router without any issue.
You can install it with opkg and the configuration is done like on Debian/Ubuntu, as OpenWRT is not "aware" of it so it doesn't really have uci commands.
Pretty easy to configure also once you get familiar with its configuration file.
The SSL termination in my case is done on a VPS in a datacenter also on HAProxy (as I have a dynamic wan ip and sometimes I even get a CGNAT ip), and the traffic is sent through a VPN tunnel to my OpenWRT. In your case, it depends if you are OK with clear text traffic on your LAN (then do the termination on the router, IF you have enough CPU power on your router), or on the servers otherwise.

BTW, you can leave uHTTPd listening on 80/443 but limit it to LAN interface, as HAProxy/NGinx will listen on the same ports but on the WAN interface.

1 Like