Files
Kenji M 22d17d39f9 zet: document UFW rules required for nginx on LAN
Ports 80 and 443 must be open in UFW so LAN clients using split DNS
can reach nginx directly without going through pfSense NAT.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 15:08:17 +00:00
..

nginx — zet.home.arpa

SSL-terminating reverse proxy. Handles all inbound HTTPS traffic and routes to backend services by hostname.

Overview

Field Value
Package nginx (Ubuntu apt)
Config /etc/nginx/sites-available/kenjim.conf
SSL cert /etc/nginx/ssl/kenjim.com/ (managed by acme.sh)
Ports 80/tcp (HTTP→HTTPS redirect), 443/tcp (HTTPS)
Service nginx.service (systemd, enabled)

Architecture

Internet → pfSense NAT (80,443) → nginx on 172.27.0.35
                                       │
                              ┌────────┴─────────┐
                         git.kenjim.com     (future)
                              │
                           Gitea :3000

LAN clients resolve *.kenjim.com subdomains directly to 172.27.0.35 via split DNS (Pi-hole + pfSense Unbound host overrides), avoiding hairpin NAT through pfSense's WAN interface.

Virtual Hosts

Hostname Backend Notes
git.kenjim.com http://127.0.0.1:3000 Gitea (systemd service)
www.kenjim.com http://127.0.0.1:8080 Update port when container is running
kenji.kenjim.com http://127.0.0.1:8082 Update port when container is running
gt.kenjim.com Returns 444 (CNAME points elsewhere)
default (unknown host) Returns 444 (drops connection)

Config File

Location: /etc/nginx/sites-available/kenjim.conf
Repo copy: kenjim.conf

To add a new Docker container backend, add a new server {} block following the existing pattern and update the proxy_pass port to match the container's host port mapping.

SSL Certificate

Certificate is managed by acme.sh — see ../ssl/.

File Path
Full chain /etc/nginx/ssl/kenjim.com/fullchain.pem
Private key /etc/nginx/ssl/kenjim.com/key.pem

Directory: owned by kenjim:www-data, mode 750.
Sudoers rule at /etc/sudoers.d/acme-nginx-reload allows acme.sh to reload nginx without a password on cert renewal.

Service Management

sudo systemctl status nginx
sudo systemctl reload nginx      # reload config (no downtime)
sudo systemctl restart nginx     # full restart
sudo nginx -t                    # test config syntax before applying

UFW Firewall Rules

Ports 80 and 443 must be open in UFW on zet for LAN clients to reach nginx directly (split DNS bypasses pfSense NAT):

sudo ufw allow 80/tcp comment 'nginx HTTP'
sudo ufw allow 443/tcp comment 'nginx HTTPS'

Current UFW status also allows: Samba, NFS (LAN only), SSH (22), Squid (3128), Gitea (3000).

pfSense NAT Rules

WAN Port Redirect to Port Description
80/tcp 172.27.0.35 80 HTTP → nginx (redirects to HTTPS)
443/tcp 172.27.0.35 443 HTTPS → nginx

Adding a New Docker Container

  1. Start the container with a host port mapping, e.g. -p 8083:80
  2. Add a server block to /etc/nginx/sites-available/kenjim.conf:
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name newservice.kenjim.com;

    ssl_certificate     /etc/nginx/ssl/kenjim.com/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/kenjim.com/key.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers   HIGH:!aNULL:!MD5;

    location / {
        proxy_pass         http://127.0.0.1:8083;
        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;
    }
}
  1. Add the domain to the cert's SAN list if not already covered (see ../ssl/)
  2. Add a CNAME in GoDaddy: newservicelair.kenjim.com
  3. Add split DNS overrides in Pi-hole and pfSense Unbound
  4. Test and reload: sudo nginx -t && sudo systemctl reload nginx

Migration Notes

To move nginx to a new server:

  1. sudo apt install nginx
  2. Copy /etc/nginx/sites-available/kenjim.conf
  3. Copy /etc/nginx/ssl/kenjim.com/ (cert files)
  4. Copy /etc/sudoers.d/acme-nginx-reload
  5. Re-run acme.sh --install-cert to wire up the renewal hook to the new host
  6. Update pfSense NAT rules to point to the new host IP
  7. Update split DNS overrides to the new host IP