# Network Topology Two views of the same network. The trust-tier diagram is how I *reason* about it. The physical-flow one is for when someone asks "but where does it actually plug in." ## Trust tiers and policy Seven VLANs grouped by how much I trust what's on them. Edges are allowed inter-tier flows; everything else is default-deny. ```mermaid graph TB subgraph UNTRUSTED["Untrusted — internet only, no internal access"] GUEST[Guest WiFi] IOT[IoT] WFH[Work-from-home] end subgraph PUBLIC["Public-facing"] DMZ[DMZ
reverse proxy + public services] end subgraph TRUSTED["Trusted"] LAN[LAN
personal devices] INT[Internal services
app stack] end subgraph MGMT["Management — VPN-only"] ADMIN[Hypervisor, firewall,
backup, switches, APs] end subgraph REMOTE["Remote"] VPN[WireGuard clients] end INTERNET((Internet)) UNTRUSTED -->|outbound only| INTERNET INTERNET -->|HTTP/HTTPS
tight allowlist| DMZ INTERNET -->|WireGuard
UDP| VPN DMZ -.->|narrow allowlist
firewall-enforced| INT LAN -->|consume services| INT VPN -->|LAN-equivalent +
admin access| INT VPN --> ADMIN classDef untrusted fill:#3a1f1f,stroke:#8b3a3a,color:#f0d0d0 classDef public fill:#3a2f1f,stroke:#8b6b3a,color:#f0e0d0 classDef trusted fill:#1f3a2f,stroke:#3a8b6b,color:#d0f0e0 classDef mgmt fill:#1f2f3a,stroke:#3a6b8b,color:#d0e0f0 classDef remote fill:#2f1f3a,stroke:#6b3a8b,color:#e0d0f0 class GUEST,IOT,WFH untrusted class DMZ public class LAN,INT trusted class ADMIN mgmt class VPN remote ``` ## Physical flow What plugs into what. Tier labels, not addresses. ```mermaid graph LR ISP[ISP] --> GW[Carrier gateway
passthrough mode] GW --> FW[pfSense firewall] FW --> SW[Managed switch
VLAN-aware] SW --> T_MGMT[MGMT tier] SW --> T_INT[Internal services tier] SW --> T_LAN[LAN tier] SW --> T_WFH[WFH tier] SW --> T_IOT[IoT tier] SW --> T_GUEST[Guest tier] SW --> T_DMZ[DMZ tier] FW -.->|VPN concentrator| VPN[WireGuard] ``` ## Why two reverse proxies, not one The DMZ-to-internal arrow above does a lot of work, so worth being explicit. There are two Caddy instances: - One in the DMZ, internet-facing, fronting a deliberately small set of public services. - One in the internal services tier, LAN/VPN only, fronting everything else. The first version of this was a single Caddy cloned into the DMZ doing both jobs. It "worked," in the sense that nothing was on fire — but every internal admin surface was technically internet-reachable, gated only by app-level auth. Once I drew it out I realized I'd built exactly the thing the DMZ was supposed to prevent. Splitting them was the fix: the DMZ Caddy can only see the small handful of backends it's allowed to reach, the firewall enforces that independently of the proxy config, and VPN clients hit the internal Caddy directly without ever touching the DMZ. This is the layered-controls principle from `SECURITY.md` made concrete. Both the proxy and the firewall enforce the same allowlist. Misconfiguring the proxy is way easier than misconfiguring the firewall, so they back each other up. ## Notes - Inter-tier policy is enforced at the firewall. Intra-tier traffic between hosts on the same bridge does not — see `NETWORK.md` for why that matters when reasoning about blast radius. - Subnets, VLAN IDs, hardware models, and ISP details live in the private repo. The trust tiers are the part worth publishing; the IP plan isn't.