# Homelab Networking Model ## Physical Network - **Gear:** UniFi throughout - **Gateway / controller:** UDM Pro (`10.5.0.1`, WAN `69.166.182.157`) - **Core / access switching:** - USW-24-PoE (`10.5.0.10`) - USW Pro HD 24 (`10.5.0.135`) - **Wi-Fi access points:** - U7 Pro (`10.5.0.21`) — active - U6 LR (`10.5.0.20`) — currently disconnected in UniFi as of 2026-05-21 - **Management subnet:** `10.5.0.0/24` - **Trusted subnet:** `10.5.1.0/24` (VLAN 51) - **IoT subnet:** `10.5.10.0/24` (VLAN 510) - **Camera subnet:** `10.5.20.0/24` (VLAN 520) - **Servers subnet:** `10.5.30.0/24` (VLAN 30) - **Guest subnet:** `10.5.90.0/24` (VLAN 590) - **Legacy quarantine:** `192.168.1.0/24` (`Old IoT`, VLAN 2) - **UniFi policy zones:** - `Internal` = Management + Trusted + Servers - `Untrusted` = IoT + Camera + Old IoT - `Hotspot` = Guest - **Current custom policy additions on top of UniFi defaults:** - `Allow Internal to Untrusted` - `Block Untrusted to Gateway Admin Surfaces` (blocks IoT/Camera/Old IoT access to the UDM Pro admin TCP ports while leaving DHCP/DNS/mDNS/internet behavior to the existing zone defaults) - **Serenity IP:** 10.5.30.5 - **N.O.M.A.D. IP:** 10.5.30.7 - **PlausibleDeniability:** 10.5.30.6 (Servers VLAN) ## Remote Access - **Pangolin VPS + Newt:** Services exposed as subdomains via reverse proxy. Newt agents run on PD and N.O.M.A.D. - **Tailscale:** Personal remote access, runs on Serenity (100.94.87.79) - **Cloudflared:** No longer used. Dead container on Serenity to be removed. ## DNS - **Provider:** Cloudflare - All public subdomains point at Pangolin VPS IP ## Known Public Subdomains - `paccoco.com` → Pangolin VPS - `panel.paccoco.com` → Pelican Panel (N.O.M.A.D.) - `node1.paccoco.com` → Wings daemon (N.O.M.A.D., no auth) - `meshmonitor.paccoco.com` → Meshmonitor (PD) - `gitea.paccoco.com` → Gitea (PD) - `ai.paccoco.com` → OpenWebUI (PD) — DNS/Pangolin resource pending ## Docker Networking (PlausibleDeniability) ### ix-databases_shared-databases Created by the `databases` stack. The databases compose file uses `name: ix-databases` so Docker names the network `ix-databases_shared-databases`, matching what all other stacks declare as external. Any stack connecting to shared-postgres, shared-mariadb, or shared-redis must declare: ```yaml networks: ix-databases_shared-databases: external: true ``` ### pangolin Created at runtime by the `newt` container in the infrastructure stack. Any service needing reverse-proxy exposure must declare: ```yaml networks: pangolin: external: true ``` ### Internal Ingress Pattern - Pangolin remains the public edge on the VPS. - PD now runs an internal-only Traefik container on the `pangolin` network. - Secure routed apps should move toward: `Pangolin -> Traefik -> app`. - Traefik does not mount `docker.sock`; routes are explicit file-provider config. - Authelia is the policy decision point for per-domain and per-group access. - Internal services can stay HTTP-only behind Traefik unless a backend specifically needs HTTPS. ### Internal Service Model Internal services run HTTP only behind the reverse proxy. Compose service names used for internal DNS between services in the same stack/network. ## N.O.M.A.D. Networking Notes - `panel.paccoco.com` added to `/etc/hosts` → `127.0.0.1` for NAT loopback - nginx listens on 80 and 443 (self-signed cert) for Wings → Panel communication - Wings uses `--ignore-certificate-errors` for local loopback - Pangolin resource `node1.paccoco.com` has auth disabled (Wings handles its own auth) - Minecraft port 25565 TCP/UDP goes directly via home router port forward, not through Pangolin