header-logo-left

The Lone Geek Blog

One geek in a sea of nerds.

header-logo-left

Nginx Proxy Sandwitch With NAT

Nginx proxying to docker inside nat

| Comments

Public Nginx Server using a proxy connection

V

Router using nat forwarding on a high port

V

Home Server running docker + nginx proxy

V

Docker container running codimd


My latest project, a proxy-nat sandwich. It comprises of a nginx proxy on both the public server and the local server sitting behind a router and the traffic is entirely encrypted with standard ssl web certs.

If you don’t know what these are, here’s a primer. The proxy just takes advantage of nginx’s native features, what it’s generally known for doing. Proxing connections to frontend web apps and backend services. I’m not sure how best describe it so here’s a quote from wikipedia.

In computer networking, port forwarding or port mapping is an application of network address translation that redirects a communication request from one address and port number combination to another while the packets are traversing a network gateway, such as a router or firewall.

The router part is simply a nat port forwarding some port on the wan interface to a local server. I just picked a number between 1000 and 10000 that I didn’t expect to need for anything else.

The proxy on the local server takes that request and sends it onto a docker container running a service, codimd and likely to be others, just depends on what I want exposed to the public.

Below are some snippets of the nginx configs and I’ll drop a link to port forwarding on pfsense to save a Google process. :)

This is part of my local nginx docker config. It goes in the nginx.conf file due to the upstream bits. The whole config could probably be adjusted to allow for each site to have it’s own config. Codimd is running in a container within the same network as nginx on my fileserver.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
        # Codimd
        upstream codimd {
                server        codimd:3000;
        }

                server {
                listen        80;
                server_name   codimd.localservices;

                location / {
                        proxy_pass  http://codimd;
                }
        }

        server {
                server_name   codimd.localservices;
                listen 443 ssl;
                ssl_certificate /config/keys/home-certificate.crt;
                ssl_certificate_key /config/keys/home-certificate.key;

                location / {
                        proxy_pass  http://codimd;
                }
        }

This part goes on the public nginx server. It serves as the relay and connects to a ssl only port with pre-established ssl certs on both servers. A port has to be forwarded and open on the firewall between them.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
server {
        server_name codimd.mydomain.com;
        location / {
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_ssl_trusted_certificate /home/michael/certs/home-certificate.crt;
        proxy_ssl_verify       on;
        proxy_ssl_verify_depth 2;
                proxy_pass https://home.mydomain.com:12345; # not a valid location so no funny business.
        }


    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/codimd.mydomain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/codimd.mydomain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = codimd.mydomain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        server_name codimd.mydomain.com;
    listen 80;
    return 404; # managed by Certbot


}

Purpose?

So I can setup some handy services that may not be feasible to run entirely on a public server. Something for family and friends or just me so I wouldn’t need to open a VPN back home just to use the app. I’m going to use docker for most of it. Those are generally easy to setup, well, at least the ones I find easy to configure. lol. If docker proves complicated for a app then a proxmox container or VM should do.

Yup, that should be it. Cheers my fellow nerds.

Comments