Files
truenas-stacks/docs/architecture/NETWORKING_MODEL.md
Fizzlepoof 9e0f66c2b6
Some checks failed
secret-guardrails / artifact-secret-scan (push) Has been cancelled
secret-guardrails / gitleaks (push) Has been cancelled
docs: capture DNS resilience and Technitium backup sync
2026-05-24 02:49:23 +00:00

4.8 KiB

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
    • Allow Untrusted to DNS Resolver
    • Block Untrusted to Gateway Default Services
    • Allow Untrusted to Gateway DHCP
    • Allow Untrusted to Gateway mDNS
    • explicit Allow Public DNS fallbacks
  • Current DHCP DNS policy:
    • Management, Trusted, Servers, IoT, Camera, and Old IoT advertise 10.5.30.8, 10.5.30.9, 10.5.30.10, and 9.9.9.9 via DHCP
    • Guest advertises 9.9.9.9 and 1.1.1.1
  • Current hardening result: every non-guest lane now has three internal Technitium resolvers for both public DNS and the private home.paccoco.com zone, plus an external fallback for general internet name resolution; IoT/Camera/Old IoT keep DNS, DHCP, and mDNS, but general Untrusted -> Gateway access and UDM Pro admin-surface access are blocked
  • Current sync model: PD (10.5.30.8) is the Technitium source of truth, and root cron on PD runs /mnt/docker-ssd/docker/compose/technitium-pilot/bin/sync_backup_nodes.sh every 15 minutes to push the live config to N.O.M.A.D. (10.5.30.9) and Serenity (10.5.30.10), restart those backup nodes, and verify both dns.home.paccoco.com and a public recursive lookup
  • Current DNS caveats: 9.9.9.9 is only a public-DNS fallback and does not preserve authoritative internal-zone behavior by itself; same-host checks against macvlan IPs are not reliable, so health verification must come from another host or client on the LAN/VLAN
  • 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:

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:

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/hosts127.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