feat: introduce eraser diagrams

This commit is contained in:
Brian Pooe 2026-03-21 23:35:27 +02:00
parent e6f9a5f2e8
commit a214436b8d
7 changed files with 478 additions and 310 deletions

View file

@ -166,7 +166,7 @@ beszel.{{CADDY_BASE_DOMAIN:-home.example.com}} {
drawio.{{CADDY_BASE_DOMAIN:-home.example.com}} {
import common
redir / /draw/ 308
reverse_proxy 192.168.10.9:8080
reverse_proxy {{CADDY_OFFICE_PREFIX:-10.10.0}}.9:8080
}
gramps.{{CADDY_BASE_DOMAIN:-home.example.com}} {

View file

@ -1,5 +1,8 @@
# pfSense Rule Set: Force DNS on LAN + All VLANs
> Status note (2026-03-21): In the current pfSense backup, this runbook has already been applied (LAN + Office + Family + IoT + Media + Guest redirects present).
> Keep this file as implementation/reference guidance.
This runbook enforces DNS redirection to your local resolver (`10.60.0.5`) across:
- LAN (`10.1.0.0/24`)
- Office / OPT2 (`10.10.0.0/24`)
@ -9,7 +12,7 @@ This runbook enforces DNS redirection to your local resolver (`10.60.0.5`) acros
- Guest / OPT6 (`10.50.0.0/24`)
## Why this is needed
Right now, redirect NAT is only on LAN. VLAN clients can still bypass your DNS filter by hardcoding public DNS on port 53.
If this runbook has not yet been applied in your environment, VLAN clients can bypass your DNS filter by hardcoding public DNS on port 53.
## Prerequisites
- DNS server IP remains `10.60.0.5` (Pi-hole now, Technitium later).

View file

@ -1,5 +1,8 @@
# pfSense + Pi-hole DNS Architecture Analysis and Technitium Mapping
> Status note (2026-03-21): This document is a historical analysis snapshot from an earlier backup/cutover stage.
> Current-state network documentation is maintained in `docs/network/homelab-network.md` using public-safe notation (`10.x.x.x`, `home.example.com`).
## Scope and source files
- pfSense backup: `/Users/luda/Downloads/config-pfSense.home.arpa-20260301104624.xml`
- Pi-hole teleporter: `/Users/luda/Downloads/pi-hole-raspberrypihole-teleporter_2026-03-01_08-38-24.tar.gz`

View file

@ -0,0 +1,67 @@
cloud-architecture-diagram
title Homelab Logical Segmentation and Access Policy (Sanitized)
direction right
VLAN_Segments [color: blue, icon: server] {
LAN [icon: monitor, label: "LAN (10.1.0.0/24)"]
Office [icon: monitor, label: "Office (10.10.0.0/24)"]
Family [icon: wifi, label: "Family (10.20.0.0/24)"]
IoT [icon: wifi, label: "IoT (10.30.0.0/24)"]
Media [icon: monitor, label: "Media (10.40.0.0/24)"]
Guest [icon: wifi, label: "Guest (10.50.0.0/24)"]
AdBlock [icon: server, label: "AdBlock (10.60.0.0/24)"]
}
pfSense_Policy [color: red, icon: shield] {
NetgatePolicy [icon: shield, label: "pfSense Policy Plane"]
DNSRedirect [icon: server, label: "DNS NAT Redirect (53 -> LOCAL_DNS)"]
}
Service_Anchors [color: green, icon: server] {
TechnitiumDNS [icon: server, label: "Technitium DNS (10.60.0.5)"]
CaddyHost [icon: server, label: "CADDY_HOST (10.10.0.5)"]
RFC1918Networks [icon: server, label: "Other Private Networks (RFC1918)"]
Internet [icon: globe]
}
// Routed policy path
LAN > NetgatePolicy: routed policy
Office > NetgatePolicy: routed policy
Family > NetgatePolicy: routed policy
IoT > NetgatePolicy: routed policy
Media > NetgatePolicy: routed policy
Guest > NetgatePolicy: routed policy
AdBlock > NetgatePolicy: routed policy
NetgatePolicy > DNSRedirect: firewall/NAT control
NetgatePolicy > Internet: internet egress
// DNS dependency (forced DNS on client VLANs)
LAN --> TechnitiumDNS: forced DNS
Office --> TechnitiumDNS: forced DNS (except CADDY_HOST source)
Family --> TechnitiumDNS: forced DNS
IoT --> TechnitiumDNS: forced DNS
Media --> TechnitiumDNS: forced DNS
Guest --> TechnitiumDNS: forced DNS
// Intent-based policy highlights
Family > CaddyHost: limited TCP allow
Media > CaddyHost: limited TCP allow
Office > CaddyHost: local Office services
Family > RFC1918Networks: blocked except explicit allows [color: red]
IoT > RFC1918Networks: blocked except explicit allows [color: red]
Media > RFC1918Networks: blocked except explicit allows [color: red]
Guest > RFC1918Networks: blocked except explicit allows [color: red]
Office > RFC1918Networks: broad internal access
AdBlock > RFC1918Networks: broad internal access (current state)
TechnitiumDNS > Internet: upstream DNS/update access
legend [position: bottom-left] {
[connection: >, label: Routed/allowed policy path]
[connection: -->, label: Forced DNS dependency]
[color: red, label: Isolation or deny-boundary intent]
[color: blue, label: VLAN client segments]
[color: green, label: Service anchors]
}

View file

@ -0,0 +1,75 @@
cloud-architecture-diagram
title Homelab Physical Topology (Current)
direction right
WAN_Internet_Edge [color: red, icon: globe] {
Internet [icon: globe]
Calix_ONT [icon: server, label: "Calix GigaPoint 803G ONT"]
}
Routing_Core [color: blue, icon: shield] {
Netgate1100 [icon: server, label: "Netgate 1100 pfSense"]
}
Core_Services [color: red, icon: server] {
RaspberryPi4 [icon: server, label: "Raspberry Pi 4 (2GB) Technitium DNS/AdBlock"]
}
Distribution [color: green, icon: server] {
USW_Lite8PoE [icon: server, label: "UB-USW-LITE-8-POE"]
}
Media_Segment [color: orange, icon: monitor] {
TLSG108 [icon: server, label: "TL-SG108"]
TV [icon: monitor]
AppleTV_Console [icon: play, label: "Apple TV / Console"]
}
WiFi_Client_Zones [color: green, icon: wifi] {
UniFiU6LR [icon: wifi, label: "UniFi U6-LR Managed AP"]
Family [icon: wifi]
Guest [icon: wifi]
IoT [icon: wifi]
}
Office_Homelab_Devices [color: blue, icon: server] {
TLSG1016DE [icon: server, label: "TL-SG1016DE"]
IntelNUC [icon: server, label: "Intel NUC"]
SynologyDS920 [icon: server, label: "Synology DS920+"]
CaddyHost [icon: server, label: "Office Reverse Proxy (Caddy Host)"]
MacMini [icon: monitor, label: "Mac mini"]
OtherOfficeInfra [icon: server, label: "Other Office Infra"]
}
// Wired and wireless relationships
Internet > Calix_ONT
Calix_ONT > Netgate1100
Netgate1100 > USW_Lite8PoE: LAN/VLAN trunk
USW_Lite8PoE > UniFiU6LR: trunk + PoE
USW_Lite8PoE > TLSG108: media uplink
USW_Lite8PoE > TLSG1016DE: office uplink
USW_Lite8PoE > RaspberryPi4: DNS host link
USW_Lite8PoE > MacMini: LAN endpoint
TLSG108 > TV
TLSG108 > AppleTV_Console
UniFiU6LR --> Family: wireless
UniFiU6LR --> Guest: wireless
UniFiU6LR --> IoT: wireless
TLSG1016DE > IntelNUC
TLSG1016DE > SynologyDS920
TLSG1016DE > CaddyHost
TLSG1016DE > OtherOfficeInfra
// Logical resolver path (not a direct cable)
Netgate1100 --> RaspberryPi4: DNS query path
legend [position: bottom-left] {
[connection: >, label: Wired Ethernet]
[connection: -->, label: Wireless or logical path]
[color: red, label: Internet edge / DNS critical path]
[color: blue, label: Routing and office zones]
[color: green, label: Distribution and access zones]
}

View file

@ -1,253 +1,251 @@
<mxfile host="app.diagrams.net" modified="2026-03-21T00:00:00.000Z" agent="Codex" version="24.7.17" type="device" compressed="false">
<diagram id="physical-topology" name="Physical Topology">
<mxGraphModel dx="1800" dy="1200" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="2800" pageHeight="1800" math="0" shadow="0">
<mxfile host="drawio.home.brianpooe.com" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36" compressed="false" version="29.6.4" pages="2">
<diagram id="homelab-physical" name="Home Network (Physical Zones)">
<mxGraphModel dx="2043" dy="1868" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="2400" pageHeight="1400" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="2" value="Homelab Network - Physical Topology" style="text;html=1;align=left;verticalAlign=top;fontSize=30;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="40" y="20" width="900" height="50" as="geometry" />
<mxCell id="t1" parent="1" style="text;html=1;align=left;verticalAlign=top;fontSize=28;fontStyle=1;" value="Homelab Physical Topology (Template-Inspired)" vertex="1">
<mxGeometry height="40" width="1000" x="30" y="20" as="geometry" />
</mxCell>
<mxCell id="3" value="Icon-first layout with reduced edge labels for readability" style="text;html=1;align=left;verticalAlign=top;fontSize=14;fontStyle=2;" vertex="1" parent="1">
<mxGeometry x="40" y="64" width="700" height="24" as="geometry" />
<mxCell id="zone_wan" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=12;labelBackgroundColor=none;fillColor=#f8cecc;strokeColor=#b85450;opacity=60;container=1;collapsible=0;dashed=1;dashPattern=1 4;align=right;verticalAlign=top;spacingRight=-95;spacingTop=-16;fontColor=#330000;labelPosition=left;verticalLabelPosition=bottom;" value="WAN / Internet Edge" vertex="1">
<mxGeometry height="240" width="430" x="30" y="100" as="geometry" />
</mxCell>
<mxCell id="4" value="Internet Edge" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#b3b3b3;dashed=1;" vertex="1" parent="1">
<mxGeometry x="20" y="120" width="860" height="260" as="geometry" />
<mxCell id="zone_core" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=12;labelBackgroundColor=none;fillColor=#dae8fc;strokeColor=#6c8ebf;opacity=65;container=1;collapsible=0;dashed=1;dashPattern=1 4;align=right;verticalAlign=top;spacingRight=-70;spacingTop=-16;fontColor=#001933;labelPosition=left;verticalLabelPosition=bottom;" value="Routing Core" vertex="1">
<mxGeometry height="240" width="520" x="500" y="100" as="geometry" />
</mxCell>
<mxCell id="5" value="Core and Distribution" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#b3b3b3;dashed=1;" vertex="1" parent="1">
<mxGeometry x="900" y="20" width="1860" height="1540" as="geometry" />
<mxCell id="zone_dist" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=12;labelBackgroundColor=none;fillColor=#d5e8d4;strokeColor=#82b366;opacity=65;container=1;collapsible=0;dashed=1;dashPattern=1 4;align=right;verticalAlign=top;spacingRight=-75;spacingTop=-16;fontColor=#003300;labelPosition=left;verticalLabelPosition=bottom;" value="Distribution" vertex="1">
<mxGeometry height="240" width="520" x="1060" y="100" as="geometry" />
</mxCell>
<mxCell id="10" value="☁ Internet / Fibre&#xa;500/500 Mbps" style="shape=cloud;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=17;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="80" y="210" width="230" height="120" as="geometry" />
<mxCell id="zone_wifi" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=12;labelBackgroundColor=none;fillColor=#e1d5e7;strokeColor=#9673a6;opacity=60;container=1;collapsible=0;dashed=1;dashPattern=1 4;align=right;verticalAlign=top;spacingRight=-105;spacingTop=-16;fontColor=#330066;labelPosition=left;verticalLabelPosition=bottom;" value="Wi-Fi Client Zones" vertex="1">
<mxGeometry height="430" width="740" x="1610" y="60" as="geometry" />
</mxCell>
<mxCell id="11" value="🔌 Calix GigaPoint 803G&#xa;GPON ONT" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=16;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="370" y="220" width="250" height="100" as="geometry" />
<mxCell id="zone_media" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=12;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;opacity=65;container=1;collapsible=0;dashed=1;dashPattern=1 4;align=right;verticalAlign=top;spacingRight=-90;spacingTop=-16;fontColor=#663300;labelPosition=left;verticalLabelPosition=bottom;" value="Media Segment" vertex="1">
<mxGeometry height="270" width="520" x="1060" y="450" as="geometry" />
</mxCell>
<mxCell id="12" value="🛡 Netgate 1100&#xa;pfSense" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=16;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="680" y="210" width="200" height="120" as="geometry" />
<mxCell id="tlsg108" parent="zone_media" style="fillColorStyles=neutralFill;neutralFill=#9DA6A8;shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#FFFFFF;strokeColor=#000000;gradientColor=#5B6163;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.hub;network2IconW=1;network2IconH=0.30;labelBackgroundColor=none;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;spacingTop=6;fontSize=11;" value="TL-SG108" vertex="1">
<mxGeometry height="100" width="180" x="110" y="100" as="geometry" />
</mxCell>
<mxCell id="13" value="🧠 UB-USW-LITE-8-POE&#xa;Managed Core PoE Switch" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=16;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="980" y="200" width="380" height="140" as="geometry" />
<mxCell id="media_console" parent="zone_media" style="shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#EDEDED;strokeColor=#000000;gradientColor=#5B6163;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.gamepad;network2IconW=1;network2IconH=0.74;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;labelBackgroundColor=none;fontSize=10;" value="Apple TV / Console" vertex="1">
<mxGeometry height="100" width="145" x="340" y="160" as="geometry" />
</mxCell>
<mxCell id="20" value="📶 UniFi U6 LR&#xa;Managed AP&#xa;(VLAN trunk distribution)" style="shape=ellipse;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=15;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="1480" y="70" width="320" height="170" as="geometry" />
<mxCell id="e10" edge="1" parent="zone_media" source="tlsg108" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2.4;endSize=12;endArrow=block;endFill=1;exitX=1;exitY=0.70;exitDx=0;exitDy=0;entryX=0;entryY=0.60;entryDx=0;entryDy=0;" target="media_console">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="21" value="👨‍👩‍👧 Family Wi-Fi Clients" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="1890" y="45" width="290" height="70" as="geometry" />
<mxCell id="zone_office" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=12;labelBackgroundColor=none;fillColor=#dae8fc;strokeColor=#6c8ebf;opacity=60;container=1;collapsible=0;dashed=1;dashPattern=1 4;align=right;verticalAlign=top;spacingRight=-125;spacingTop=-16;fontColor=#001933;labelPosition=left;verticalLabelPosition=bottom;" value="Office / Homelab Devices" vertex="1">
<mxGeometry height="420" width="740" x="1610" y="530" as="geometry" />
</mxCell>
<mxCell id="22" value="🙋 Guest Wi-Fi Clients" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="1890" y="125" width="290" height="70" as="geometry" />
<mxCell id="zone_services" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=12;labelBackgroundColor=none;fillColor=#f8cecc;strokeColor=#b85450;opacity=60;container=1;collapsible=0;dashed=1;dashPattern=1 4;align=right;verticalAlign=top;spacingRight=-95;spacingTop=-16;fontColor=#330000;labelPosition=left;verticalLabelPosition=bottom;" value="Core Services" vertex="1">
<mxGeometry height="270" width="520" x="500" y="380" as="geometry" />
</mxCell>
<mxCell id="23" value="🔌 IoT Wi-Fi Clients" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="1890" y="205" width="290" height="70" as="geometry" />
<mxCell id="pi" parent="zone_services" style="fillColorStyles=neutralFill;neutralFill=#9DA6A8;shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#EDEDED;strokeColor=#660000;gradientColor=none;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.server;network2IconW=1;network2IconH=0.58;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;labelBackgroundColor=none;fontSize=10;fontColor=#660000;" value="Raspberry Pi 4 (2GB)&#xa;Technitium DNS/AdBlock" vertex="1">
<mxGeometry height="120" width="160" x="220" y="85" as="geometry" />
</mxCell>
<mxCell id="24" value="🔀 TP-Link TL-SG108&#xa;Unmanaged Media Switch" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;fontSize=15;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="1480" y="330" width="340" height="130" as="geometry" />
<mxCell id="internet" parent="1" style="shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#EDEDED;strokeColor=#000000;gradientColor=#5B6163;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.globe;network2IconW=1;network2IconH=1;labelBackgroundColor=none;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;fontSize=10;" value="Internet" vertex="1">
<mxGeometry height="95" width="95" x="70" y="165" as="geometry" />
</mxCell>
<mxCell id="25" value="📺 Media Clients Group&#xa;(Samsung TV, Apple TV, Soundbar, etc.)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="1890" y="345" width="380" height="100" as="geometry" />
<mxCell id="ont" parent="1" style="fillColorStyles=neutralFill;neutralFill=#9DA6A8;shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#EDEDED;strokeColor=#000000;gradientColor=#5B6163;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.modem;network2IconW=1;network2IconH=0.30;labelBackgroundColor=none;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;spacingTop=6;fontSize=11;" value="Calix GigaPoint 803G&#xa;ONT" vertex="1">
<mxGeometry height="90" width="170" x="220" y="168" as="geometry" />
</mxCell>
<mxCell id="26" value="🔀 TP-Link TL-SG1016DE&#xa;Managed Office/Homelab Switch" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=15;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="1480" y="520" width="360" height="140" as="geometry" />
<mxCell id="pfsense" parent="1" style="shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#EDEDED;strokeColor=#660000;gradientColor=none;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.firewall;network2IconW=1;network2IconH=0.62;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;labelBackgroundColor=none;fontSize=11;" value="Netgate 1100&#xa;pfSense" vertex="1">
<mxGeometry height="95" width="140" x="670" y="163" as="geometry" />
</mxCell>
<mxCell id="27" value="🖥 Intel NUC" style="shape=cylinder;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="1890" y="500" width="230" height="80" as="geometry" />
<mxCell id="usw" parent="1" style="fillColorStyles=neutralFill;neutralFill=#9DA6A8;shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#FFFFFF;strokeColor=#000000;gradientColor=#5B6163;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.hub;network2IconW=1;network2IconH=0.30;labelBackgroundColor=none;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;spacingTop=6;fontSize=11;" value="UB-USW-LITE-8-POE" vertex="1">
<mxGeometry height="100" width="190" x="1210" y="160" as="geometry" />
</mxCell>
<mxCell id="28" value="💾 Synology DS920+" style="shape=cylinder;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="1890" y="595" width="230" height="80" as="geometry" />
<mxCell id="u6" parent="1" style="fillColorStyles=neutralFill;neutralFill=#9DA6A8;shape=mxgraph.networks2.icon;aspect=fixed;fillColor=none;strokeColor=#006600;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.wireless_hub;network2IconW=1;network2IconH=0.55;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;spacingTop=6;fontColor=#006600;labelBackgroundColor=none;fontSize=11;" value="UniFi U6 LR&#xa;Managed AP" vertex="1">
<mxGeometry height="110" width="170" x="1700" y="115" as="geometry" />
</mxCell>
<mxCell id="29" value="🧩 Other Office/Homelab Infra" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="1890" y="690" width="300" height="80" as="geometry" />
<mxCell id="family_client" parent="1" style="shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#EDEDED;strokeColor=#000000;gradientColor=#5B6163;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.mobile_phone;network2IconW=0.55;network2IconH=1;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;labelBackgroundColor=none;fontSize=10;" value="Family" vertex="1">
<mxGeometry height="110" width="95" x="1935" y="248" as="geometry" />
</mxCell>
<mxCell id="30" value="🖥 Mac mini" style="shape=cylinder;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=15;" vertex="1" parent="1">
<mxGeometry x="1480" y="750" width="260" height="100" as="geometry" />
<mxCell id="guest_client" parent="1" style="shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#EDEDED;strokeColor=#000000;gradientColor=#5B6163;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.laptop;network2IconW=1;network2IconH=0.57;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;labelBackgroundColor=none;fontSize=10;" value="Guest" vertex="1">
<mxGeometry height="90" width="110" x="2080" y="252" as="geometry" />
</mxCell>
<mxCell id="31" value="🍓 Raspberry Pi 4 (2GB)&#xa;DNS / AdBlock Resolver Host&#xa;AdBlock VLAN (repo docs: 10.60.0.5)" style="shape=cylinder;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=14;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="1480" y="900" width="460" height="140" as="geometry" />
<mxCell id="iot_client" parent="1" style="shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#EDEDED;strokeColor=#000000;gradientColor=#5B6163;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.monitor;network2IconW=1;network2IconH=0.75;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;labelBackgroundColor=none;fontSize=10;" value="IoT" vertex="1">
<mxGeometry height="100" width="110" x="2220" y="248" as="geometry" />
</mxCell>
<mxCell id="32" value="🌐 Office Reverse Proxy (Logical Service)&#xa;Repo DNS/docs anchor: caddy.home.example.com -> 10.10.0.5" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=14;dashed=1;" vertex="1" parent="1">
<mxGeometry x="1480" y="1110" width="560" height="130" as="geometry" />
<mxCell id="media_tv" parent="1" style="shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#EDEDED;strokeColor=#000000;gradientColor=#5B6163;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.monitor;network2IconW=1;network2IconH=0.75;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;labelBackgroundColor=none;fontSize=10;" value="TV" vertex="1">
<mxGeometry height="100" width="105" x="1430" y="445" as="geometry" />
</mxCell>
<mxCell id="40" value="Legend&#xa;🛡 firewall/router edge&#xa;🔀 switching&#xa;📶 managed AP&#xa;🖥 compute endpoint&#xa;💾 storage endpoint&#xa;🍓 DNS/adblock node&#xa;Purple boxes = client groups" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#666666;align=left;verticalAlign=top;spacingLeft=10;spacingTop=8;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="60" y="440" width="760" height="250" as="geometry" />
<mxCell id="tlsg1016" parent="1" style="fillColorStyles=neutralFill;neutralFill=#9DA6A8;shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#FFFFFF;strokeColor=#000000;gradientColor=#5B6163;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.hub;network2IconW=1;network2IconH=0.30;labelBackgroundColor=none;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;spacingTop=6;fontSize=11;" value="TL-SG1016DE" vertex="1">
<mxGeometry height="100" width="180" x="1710" y="595" as="geometry" />
</mxCell>
<mxCell id="41" value="Validation TODO: switch port maps, VLAN trunk/native settings, and SSID-to-VLAN bindings are not explicitly stored in this repo." style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;verticalAlign=middle;spacingLeft=10;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="60" y="730" width="820" height="100" as="geometry" />
<mxCell id="nuc" parent="1" style="fillColorStyles=neutralFill;neutralFill=#9DA6A8;shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#EDEDED;strokeColor=#000000;gradientColor=#5B6163;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.server;network2IconW=1;network2IconH=0.58;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;labelBackgroundColor=none;fontSize=10;" value="Intel NUC" vertex="1">
<mxGeometry height="100" width="120" x="1940" y="585" as="geometry" />
</mxCell>
<mxCell id="ds920" parent="1" style="fillColorStyles=neutralFill;neutralFill=#9DA6A8;shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#EDEDED;strokeColor=#000000;gradientColor=#5B6163;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.external_storage;network2IconW=1;network2IconH=0.80;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;labelBackgroundColor=none;fontSize=10;" value="Synology DS920+" vertex="1">
<mxGeometry height="105" width="130" x="2080" y="585" as="geometry" />
</mxCell>
<mxCell id="macmini" parent="1" style="shape=mxgraph.networks2.icon;aspect=fixed;fillColor=none;strokeColor=#000000;gradientColor=#5B6163;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.pc;network2IconW=1;network2IconH=0.71;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;labelBackgroundColor=none;fontSize=10;" value="Mac mini" vertex="1">
<mxGeometry height="100" width="120" x="1940" y="715" as="geometry" />
</mxCell>
<mxCell id="otherinfra" parent="1" style="fillColorStyles=neutralFill;neutralFill=#9DA6A8;shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#EDEDED;strokeColor=#000000;gradientColor=#5B6163;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.server;network2IconW=1;network2IconH=0.58;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;labelBackgroundColor=none;fontSize=10;" value="Other Office Infra" vertex="1">
<mxGeometry height="100" width="130" x="2080" y="715" as="geometry" />
</mxCell>
<mxCell id="legend" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#666666;align=left;verticalAlign=top;spacingLeft=10;spacingTop=8;fontSize=12;" value="Legend&#xa;Dashed containers: zone boundaries&#xa;Black links: physical wired links&#xa;Purple dashed links: wireless client associations&#xa;Red-accent node: DNS/AdBlock device" vertex="1">
<mxGeometry height="160" width="620" x="40" y="980" as="geometry" />
</mxCell>
<mxCell id="e1" edge="1" parent="1" source="internet" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2.4;endSize=12;endArrow=block;endFill=1;" target="ont">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e2" edge="1" parent="1" source="ont" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2.4;endSize=12;endArrow=block;endFill=1;" target="pfsense">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e3" edge="1" parent="1" source="pfsense" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2.4;endSize=12;endArrow=block;endFill=1;" target="usw">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e4" edge="1" parent="1" source="usw" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2.4;endSize=12;endArrow=block;endFill=1;" target="u6">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e5" edge="1" parent="1" source="u6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;dashPattern=1 2;strokeColor=#9673a6;strokeWidth=2.2;endSize=10;endArrow=block;endFill=0;exitX=1;exitY=0.35;exitDx=0;exitDy=0;entryX=0;entryY=0.35;entryDx=0;entryDy=0;" target="family_client">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e6" edge="1" parent="1" source="u6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;dashPattern=1 2;strokeColor=#9673a6;strokeWidth=2.2;endSize=10;endArrow=block;endFill=0;exitX=1;exitY=0.50;exitDx=0;exitDy=0;entryX=0;entryY=0.50;entryDx=0;entryDy=0;" target="guest_client">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e7" edge="1" parent="1" source="u6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;dashPattern=1 2;strokeColor=#9673a6;strokeWidth=2.2;endSize=10;endArrow=block;endFill=0;exitX=1;exitY=0.65;exitDx=0;exitDy=0;entryX=0;entryY=0.65;entryDx=0;entryDy=0;" target="iot_client">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e8" edge="1" parent="1" source="usw" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2.4;endSize=12;endArrow=block;endFill=1;" target="tlsg108">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e9" edge="1" parent="1" source="tlsg108" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2.4;endSize=12;endArrow=block;endFill=1;exitX=1;exitY=0.35;exitDx=0;exitDy=0;entryX=0;entryY=0.40;entryDx=0;entryDy=0;" target="media_tv">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e11" edge="1" parent="1" source="usw" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2.4;endSize=12;endArrow=block;endFill=1;" target="tlsg1016">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e12" edge="1" parent="1" source="tlsg1016" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2.4;endSize=12;endArrow=block;endFill=1;" target="nuc">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e13" edge="1" parent="1" source="tlsg1016" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2.4;endSize=12;endArrow=block;endFill=1;" target="ds920">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e14" edge="1" parent="1" source="tlsg1016" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2.4;endSize=12;endArrow=block;endFill=1;" target="macmini">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e15" edge="1" parent="1" source="tlsg1016" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2.4;endSize=12;endArrow=block;endFill=1;" target="otherinfra">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e16" edge="1" parent="1" source="usw" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2.4;endSize=12;endArrow=block;endFill=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;labelBackgroundColor=#ffffff;align=center;verticalAlign=middle;fontSize=10;" target="pi" value="Physical Ethernet (PoE)">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="100" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="10" target="11"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="101" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="11" target="12"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="102" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="12" target="13"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="103" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;" edge="1" parent="1" source="13" target="20"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="104" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;dashed=1;strokeColor=#9673a6;" edge="1" parent="1" source="20" target="21"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="105" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;dashed=1;strokeColor=#9673a6;" edge="1" parent="1" source="20" target="22"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="106" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;dashed=1;strokeColor=#9673a6;" edge="1" parent="1" source="20" target="23"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="107" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;" edge="1" parent="1" source="13" target="24"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="108" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;" edge="1" parent="1" source="24" target="25"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="109" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;" edge="1" parent="1" source="13" target="26"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="110" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;" edge="1" parent="1" source="26" target="27"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="111" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;" edge="1" parent="1" source="26" target="28"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="112" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;" edge="1" parent="1" source="26" target="29"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="113" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;" edge="1" parent="1" source="13" target="30"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="114" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;" edge="1" parent="1" source="13" target="31"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="115" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;strokeColor=#d6b656;endArrow=open;" edge="1" parent="1" source="31" target="32"><mxGeometry relative="1" as="geometry" /></mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="logical-vlan-access" name="Logical VLAN / Access Flow">
<mxGraphModel dx="1800" dy="1200" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="2800" pageHeight="1800" math="0" shadow="0">
<diagram id="homelab-logical" name="Home Network (Logical Policy)">
<mxGraphModel dx="1500" dy="1100" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="2400" pageHeight="1400" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="2" value="Homelab Network - Logical VLAN / Access Flow" style="text;html=1;align=left;verticalAlign=top;fontSize=30;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="40" y="20" width="950" height="50" as="geometry" />
<mxCell id="lt1" value="Homelab Logical Segmentation and Access Intent" style="text;html=1;align=left;verticalAlign=top;fontSize=28;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="30" y="20" width="1050" height="40" as="geometry" />
</mxCell>
<mxCell id="3" value="VLAN Segments" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#b3b3b3;dashed=1;" vertex="1" parent="1">
<mxGeometry x="40" y="110" width="830" height="980" as="geometry" />
<mxCell id="l_zone_vlans" value="VLAN Segments" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#b3b3b3;dashed=1;container=1;collapsible=0;" vertex="1" parent="1">
<mxGeometry x="30" y="100" width="900" height="780" as="geometry" />
</mxCell>
<mxCell id="4" value="Policy Engine" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#b3b3b3;dashed=1;" vertex="1" parent="1">
<mxGeometry x="920" y="110" width="840" height="520" as="geometry" />
<mxCell id="l_zone_policy" value="pfSense Policy Plane" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#b3b3b3;dashed=1;container=1;collapsible=0;" vertex="1" parent="1">
<mxGeometry x="970" y="100" width="620" height="430" as="geometry" />
</mxCell>
<mxCell id="5" value="Shared Services" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#b3b3b3;dashed=1;" vertex="1" parent="1">
<mxGeometry x="1810" y="110" width="950" height="980" as="geometry" />
<mxCell id="l_zone_services" value="Device Anchors / Policy Notes" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#b3b3b3;dashed=1;container=1;collapsible=0;" vertex="1" parent="1">
<mxGeometry x="1630" y="100" width="730" height="780" as="geometry" />
</mxCell>
<mxCell id="10" value="💼 Office VLAN&#xa;10.10.0.0/24" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=15;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="90" y="180" width="330" height="95" as="geometry" />
<mxCell id="office" value="Office VLAN&#xa;10.10.0.0/24" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;dashed=1;dashPattern=1 4;opacity=70;fontSize=13;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="80" y="160" width="260" height="95" as="geometry" />
</mxCell>
<mxCell id="11" value="👨‍👩‍👧 Family VLAN&#xa;10.20.0.0/24" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=15;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="470" y="180" width="330" height="95" as="geometry" />
<mxCell id="family" value="Family VLAN&#xa;10.20.0.0/24" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;dashed=1;dashPattern=1 4;opacity=70;fontSize=13;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="370" y="160" width="260" height="95" as="geometry" />
</mxCell>
<mxCell id="12" value="🔌 IoT VLAN&#xa;10.30.0.0/24" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=15;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="90" y="320" width="330" height="95" as="geometry" />
<mxCell id="iot" value="IoT VLAN&#xa;10.30.0.0/24" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;dashed=1;dashPattern=1 4;opacity=70;fontSize=13;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="660" y="160" width="240" height="95" as="geometry" />
</mxCell>
<mxCell id="13" value="📺 Media VLAN&#xa;10.40.0.0/24" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=15;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="470" y="320" width="330" height="95" as="geometry" />
<mxCell id="media" value="Media VLAN&#xa;10.40.0.0/24" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;dashed=1;dashPattern=1 4;opacity=70;fontSize=13;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="80" y="290" width="260" height="95" as="geometry" />
</mxCell>
<mxCell id="14" value="🙋 Guest VLAN&#xa;10.50.0.0/24" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=15;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="90" y="460" width="330" height="95" as="geometry" />
<mxCell id="guest" value="Guest VLAN&#xa;10.50.0.0/24" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;dashed=1;dashPattern=1 4;opacity=70;fontSize=13;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="370" y="290" width="260" height="95" as="geometry" />
</mxCell>
<mxCell id="15" value="🍓 AdBlock VLAN&#xa;10.60.0.0/24" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=15;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="470" y="460" width="330" height="95" as="geometry" />
<mxCell id="adblock" value="AdBlock VLAN&#xa;10.60.0.0/24" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;dashed=1;dashPattern=1 4;opacity=70;fontSize=13;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="660" y="290" width="240" height="95" as="geometry" />
</mxCell>
<mxCell id="16" value="🏠 LAN&#xa;10.1.0.0/24" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=15;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="280" y="600" width="330" height="95" as="geometry" />
<mxCell id="lan" value="LAN&#xa;10.1.0.0/24" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;dashed=1;dashPattern=1 4;opacity=70;fontSize=13;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="370" y="420" width="260" height="95" as="geometry" />
</mxCell>
<mxCell id="17" value="Wi-Fi segmentation note&#xa;U6 LR carries Family / Guest / IoT VLAN traffic" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#82b366;align=left;verticalAlign=top;spacingLeft=10;spacingTop=8;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="90" y="740" width="710" height="100" as="geometry" />
<mxCell id="pf_icon" value="pfSense" style="shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#EDEDED;strokeColor=#660000;gradientColor=none;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.firewall;network2IconW=1;network2IconH=0.62;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;labelBackgroundColor=none;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="1220" y="170" width="120" height="85" as="geometry" />
</mxCell>
<mxCell id="18" value="Isolation note&#xa;IoT and Guest are intended self-only segments&#xa;(repo docs still indicate DNS reachability to 10.60.0.5)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#d6b656;align=left;verticalAlign=top;spacingLeft=10;spacingTop=8;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="90" y="860" width="710" height="140" as="geometry" />
<mxCell id="dhcp_note" value="DHCP DNS handout (pfSense backup)&#xa;clients -&gt; 10.60.0.5" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#b85450;fontSize=12;align=left;verticalAlign=top;spacingLeft=8;spacingTop=6;" vertex="1" parent="1">
<mxGeometry x="1010" y="290" width="250" height="90" as="geometry" />
</mxCell>
<mxCell id="20" value="🛡 Netgate 1100 / pfSense" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=16;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="1230" y="180" width="250" height="130" as="geometry" />
<mxCell id="policy_note" value="Access intent (internal segmentation)&#xa;Office: broad internal access&#xa;Family/Media: limited Office destination&#xa;IoT/Guest: no general cross-VLAN access&#xa;AdBlock: broad internal access" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#b85450;fontSize=12;align=left;verticalAlign=top;spacingLeft=8;spacingTop=6;" vertex="1" parent="1">
<mxGeometry x="1270" y="290" width="300" height="155" as="geometry" />
</mxCell>
<mxCell id="21" value="DHCP DNS handout&#xa;repo docs: clients use 10.60.0.5" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#b85450;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="980" y="340" width="350" height="100" as="geometry" />
<mxCell id="state_note" value="Validated in pfSense backup (2026-03-21)&#xa;- DNS NAT redirect active on LAN + Office + Family + IoT + Media + Guest&#xa;- Office DNS rule excludes CADDY_HOST&#xa;- Public docs use sanitized 10.x + home.example.com" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;align=left;verticalAlign=top;spacingLeft=8;spacingTop=6;" vertex="1" parent="1">
<mxGeometry x="1010" y="390" width="560" height="130" as="geometry" />
</mxCell>
<mxCell id="22" value="Firewall / ACL intent&#xa;Office broad; Family/Media limited to reverse proxy; IoT/Guest isolated" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#b85450;align=left;verticalAlign=top;spacingLeft=10;spacingTop=8;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="1360" y="340" width="380" height="120" as="geometry" />
<mxCell id="svc_dns" value="Raspberry Pi 4 (Technitium DNS)&#xa;10.60.0.5 (sanitized)" style="fillColorStyles=neutralFill;neutralFill=#9DA6A8;shape=mxgraph.networks2.icon;aspect=fixed;fillColor=#EDEDED;strokeColor=#660000;gradientColor=none;network2IconShadow=1;network2bgFillColor=none;network2Icon=mxgraph.networks2.server;network2IconW=1;network2IconH=0.58;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;labelBackgroundColor=none;fontSize=11;fontColor=#660000;" vertex="1" parent="1">
<mxGeometry x="1960" y="170" width="210" height="120" as="geometry" />
</mxCell>
<mxCell id="23" value="DNS NAT policy state to confirm&#xa;analysis doc: LAN-only current&#xa;runbooks: LAN + VLAN rollout" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;verticalAlign=top;spacingLeft=10;spacingTop=8;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="980" y="470" width="760" height="120" as="geometry" />
<mxCell id="svc_domain" value="Reverse proxy policy note&#xa;Family/Media -&gt; limited Office destination&#xa;device node intentionally omitted" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#6c8ebf;fontSize=12;align=left;verticalAlign=top;spacingLeft=8;spacingTop=6;" vertex="1" parent="1">
<mxGeometry x="1710" y="320" width="620" height="105" as="geometry" />
</mxCell>
<mxCell id="30" value="🌐 Office Reverse Proxy (Caddy)&#xa;repo docs: 10.10.0.5" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=15;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="1880" y="180" width="390" height="120" as="geometry" />
<mxCell id="matrix" value="Access Matrix (Intent)&#xa;Office: broad internal access&#xa;Family/Media: limited Office destination (+ DNS path)&#xa;IoT/Guest: no general cross-VLAN access (+ DNS path)&#xa;AdBlock: broad internal access&#xa;Public docs are sanitized: 10.x + home.example.com" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#666666;fontSize=14;align=left;verticalAlign=top;spacingLeft=10;spacingTop=8;" vertex="1" parent="1">
<mxGeometry x="30" y="930" width="2330" height="190" as="geometry" />
</mxCell>
<mxCell id="31" value="🍓 DNS / AdBlock Resolver&#xa;repo docs: 10.60.0.5" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=15;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="2320" y="180" width="390" height="120" as="geometry" />
<mxCell id="legend2" value="Legend&#xa;Gray links: routed policy/control dependency&#xa;Green links: limited Office-destination policy&#xa;Blue dashed links: DNS dependency paths to Pi (Technitium)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#666666;fontSize=12;align=left;verticalAlign=top;spacingLeft=8;spacingTop=6;" vertex="1" parent="1">
<mxGeometry x="1710" y="450" width="620" height="95" as="geometry" />
</mxCell>
<mxCell id="32" value="🏷 Local DNS model&#xa;template default: home.example.com&#xa;caddy.home.example.com -> 10.10.0.5" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#6c8ebf;align=left;verticalAlign=top;spacingLeft=10;spacingTop=8;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="1880" y="340" width="830" height="120" as="geometry" />
<mxCell id="le1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;strokeWidth=2;endSize=11;endArrow=block;endFill=1;" edge="1" parent="1" source="office" target="pf_icon">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="33" value="☁ Internet / Upstream DNS" style="shape=cloud;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="2160" y="520" width="280" height="130" as="geometry" />
<mxCell id="le2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;strokeWidth=2;endSize=11;endArrow=block;endFill=1;" edge="1" parent="1" source="family" target="pf_icon">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="34" value="Access intent highlights&#xa;Family -> Office reverse proxy only&#xa;Media -> Office reverse proxy only&#xa;AdBlock -> broad internal reach" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#666666;align=left;verticalAlign=top;spacingLeft=10;spacingTop=8;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="1880" y="700" width="830" height="160" as="geometry" />
<mxCell id="le3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;strokeWidth=2;endSize=11;endArrow=block;endFill=1;" edge="1" parent="1" source="iot" target="pf_icon">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="40" value="Compact Matrix&#xa;Office: self + LAN + all VLANs&#xa;Family: self + Office reverse proxy (+ DNS path)&#xa;IoT: self only (+ DNS path)&#xa;Media: self + Office reverse proxy (+ DNS path)&#xa;Guest: self only (+ DNS path)&#xa;AdBlock: all VLANs + LAN" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#666666;align=left;verticalAlign=top;spacingLeft=10;spacingTop=8;fontSize=15;" vertex="1" parent="1">
<mxGeometry x="40" y="1140" width="2720" height="300" as="geometry" />
<mxCell id="le4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;strokeWidth=2;endSize=11;endArrow=block;endFill=1;" edge="1" parent="1" source="media" target="pf_icon">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="41" value="Legend&#xa;Green solid = allow path in intent&#xa;Blue dashed = DNS dependency flow&#xa;Gray = routed/control dependency" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#666666;align=left;verticalAlign=top;spacingLeft=10;spacingTop=8;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="1880" y="900" width="830" height="100" as="geometry" />
<mxCell id="le5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;strokeWidth=2;endSize=11;endArrow=block;endFill=1;" edge="1" parent="1" source="guest" target="pf_icon">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="le6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;strokeWidth=2;endSize=11;endArrow=block;endFill=1;" edge="1" parent="1" source="adblock" target="pf_icon">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="le7" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;strokeWidth=2;endSize=11;endArrow=block;endFill=1;" edge="1" parent="1" source="lan" target="pf_icon">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ld0" value="Resolver Path (Logical)" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;strokeWidth=2;dashed=1;dashPattern=3 3;endSize=11;endArrow=block;endFill=0;labelBackgroundColor=#ffffff;align=center;verticalAlign=middle;fontSize=10;" edge="1" parent="1" source="pf_icon" target="svc_dns">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="le8" value="Limited Office destination" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#2D7600;strokeWidth=2.4;endSize=12;endArrow=block;endFill=1;labelBackgroundColor=#ffffff;fontSize=10;" edge="1" parent="1" source="family" target="office">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="le9" value="Limited Office destination" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#2D7600;strokeWidth=2.4;endSize=12;endArrow=block;endFill=1;labelBackgroundColor=#ffffff;fontSize=10;" edge="1" parent="1" source="media" target="office">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ld1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#1A73E8;strokeWidth=2;dashed=1;dashPattern=1 2;endSize=10;endArrow=block;endFill=0;" edge="1" parent="1" source="office" target="svc_dns">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ld2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#1A73E8;strokeWidth=2;dashed=1;dashPattern=1 2;endSize=10;endArrow=block;endFill=0;" edge="1" parent="1" source="family" target="svc_dns">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ld3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#1A73E8;strokeWidth=2;dashed=1;dashPattern=1 2;endSize=10;endArrow=block;endFill=0;" edge="1" parent="1" source="iot" target="svc_dns">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ld4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#1A73E8;strokeWidth=2;dashed=1;dashPattern=1 2;endSize=10;endArrow=block;endFill=0;" edge="1" parent="1" source="media" target="svc_dns">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ld5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#1A73E8;strokeWidth=2;dashed=1;dashPattern=1 2;endSize=10;endArrow=block;endFill=0;" edge="1" parent="1" source="guest" target="svc_dns">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ld6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#1A73E8;strokeWidth=2;dashed=1;dashPattern=1 2;endSize=10;endArrow=block;endFill=0;" edge="1" parent="1" source="lan" target="svc_dns">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ld7" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;strokeWidth=2;endSize=11;endArrow=block;endFill=1;" edge="1" parent="1" source="dhcp_note" target="svc_dns">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="100" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;endArrow=open;" edge="1" parent="1" source="10" target="20"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="101" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;endArrow=open;" edge="1" parent="1" source="11" target="20"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="102" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;endArrow=open;" edge="1" parent="1" source="12" target="20"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="103" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;endArrow=open;" edge="1" parent="1" source="13" target="20"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="104" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;endArrow=open;" edge="1" parent="1" source="14" target="20"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="105" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;endArrow=open;" edge="1" parent="1" source="15" target="20"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="106" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;endArrow=open;" edge="1" parent="1" source="16" target="20"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="110" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#2D7600;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="11" target="30"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="111" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#2D7600;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="13" target="30"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="112" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#2D7600;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="15" target="30"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="120" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;strokeColor=#1A73E8;endArrow=open;" edge="1" parent="1" source="10" target="31"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="121" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;strokeColor=#1A73E8;endArrow=open;" edge="1" parent="1" source="11" target="31"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="122" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;strokeColor=#1A73E8;endArrow=open;" edge="1" parent="1" source="12" target="31"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="123" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;strokeColor=#1A73E8;endArrow=open;" edge="1" parent="1" source="13" target="31"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="124" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;strokeColor=#1A73E8;endArrow=open;" edge="1" parent="1" source="14" target="31"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="125" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;strokeColor=#1A73E8;endArrow=open;" edge="1" parent="1" source="16" target="31"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="130" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;endArrow=open;" edge="1" parent="1" source="21" target="31"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="131" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;endArrow=open;" edge="1" parent="1" source="22" target="31"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="132" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#666666;endArrow=open;" edge="1" parent="1" source="32" target="30"><mxGeometry relative="1" as="geometry" /></mxCell>
<mxCell id="133" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;strokeColor=#1A73E8;endArrow=open;" edge="1" parent="1" source="31" target="33"><mxGeometry relative="1" as="geometry" /></mxCell>
</root>
</mxGraphModel>
</diagram>

View file

@ -1,151 +1,173 @@
# Homelab Network
## 1. Overview
This document maps the homelab network using two sources:
- Primary truth: user-provided topology and access intent (2026-03-21).
- Repo evidence: DNS/pfSense runbooks, Caddy template, and environment templates.
This document reflects the current network state using:
- User-provided topology and intent.
- Repo configuration/templates.
- pfSense backup provided by user: `config-pfSense.home.arpa-20260321225944.xml` (private local file, not committed to repo).
High-level flow:
- Internet fiber enters through ISP ONT.
- ONT uplinks to pfSense (routing, VLANs, policy).
- pfSense uplinks to the core PoE switch.
- Core switch fans out to AP, downstream switches, homelab hosts, and DNS/ad-block node.
- DNS/ad-blocking is centralized on the AdBlock VLAN (`10.60.0.0/24`) with resolver service at `10.60.0.5` in repo docs.
- Reverse proxy is hosted on Office VLAN and is used as the controlled cross-VLAN destination for Family/Media access intent.
Public-safe notation policy used in this repository:
- Internal RFC1918 layout is represented as `10.<vlan>.0/24` examples.
- Internal domain is represented as `home.example.com`.
High-level design:
- Fibre Internet -> ISP ONT -> Netgate 1100/pfSense.
- pfSense trunks VLANs to core switching.
- Core switching fans out to AP, media switch, office/homelab switch, Mac mini, and Raspberry Pi DNS node.
- Technitium DNS/ad-blocking is centralized on AdBlock VLAN.
- Office-hosted reverse proxy is the controlled cross-VLAN destination for Family/Media.
Diagram source files (Eraser diagram-as-code, replacing Draw.io as editable source):
- `docs/network/diagrams/homelab-network-physical.eraserdiagram`
- `docs/network/diagrams/homelab-network-logical.eraserdiagram`
Legacy retained for now:
- `docs/network/diagrams/homelab-network.drawio`
## Evidence Table
| Fact | Value | Source file(s) | Confidence |
| Fact | Value (public-safe) | Source file(s) | Confidence |
|---|---|---|---|
| VLAN names and CIDRs are documented | LAN `10.1.0.0/24`, Office `10.10.0.0/24`, Family `10.20.0.0/24`, IoT `10.30.0.0/24`, Media `10.40.0.0/24`, Guest `10.50.0.0/24`, Adblock `10.60.0.0/24` | `dns/pfsense-pihole-technitium-analysis.md`, `dns/pfsense-forced-dns-all-vlans.md` | High |
| DNS resolver service IP | `10.60.0.5` | `dns/pfsense-forced-dns-all-vlans.md`, `.env.sample` | High |
| Office reverse proxy host/IP used in policy docs | `caddy.home.example.com` -> `10.10.0.5` (`CADDY_HOST`) | `dns/technitium-cutover-checklist.md`, `dns/pfsense-forced-dns-all-vlans.md` | High |
| Caddy base domain default | `home.example.com` (template/default) | `.env.sample`, `caddy/Caddyfile_template` | High |
| Caddy infra hostnames include switch and DNS/admin endpoints | `switchlite8poe`, `tplink16de`, `dns01`, `nas`, `proxmox`, `pbs`, etc. | `caddy/Caddyfile_template` | High |
| pfSense DNS interception status described in repo | Current-state analysis says DNS NAT redirect is LAN-only; runbooks define extension to VLANs | `dns/pfsense-pihole-technitium-analysis.md`, `dns/pfsense-forced-dns-all-vlans.md` | Medium-High |
| Raspberry Pi 4 2GB context for DNS/ad-blocking stack | Pi 4 2GB deployment and cutover steps are documented | `dns/end-to-end-migration-runbook.md`, `dns/technitium-deployment.md` | Medium |
| Physical hardware chain (ONT, Netgate, switches, AP, endpoints) | As specified by user | User brief (2026-03-21) | High |
| Active VLAN interfaces and gateways exist for LAN, Office, Family, IoT, Media, Guest, AdBlock | LAN `10.1.0.0/24`, Office `10.10.0.0/24`, Family `10.20.0.0/24`, IoT `10.30.0.0/24`, Media `10.40.0.0/24`, Guest `10.50.0.0/24`, AdBlock `10.60.0.0/24` | `config-pfSense.home.arpa-20260321225944.xml` (`<interfaces>`, `<vlans>`) | High |
| DHCP hands out centralized DNS on client segments | Clients use `10.60.0.5` as DNS on LAN + Office + Family + IoT + Media + Guest | `config-pfSense.home.arpa-20260321225944.xml` (`<dhcpd>`) | High |
| DNS platform is Technitium on Raspberry Pi in AdBlock VLAN | `LOCAL_DNS` alias points to `10.60.0.5`; static map `dns01` exists on AdBlock VLAN | `config-pfSense.home.arpa-20260321225944.xml` (`<aliases>`, `<dhcpd><opt7>`) | High |
| Forced DNS NAT is active on LAN + Office + Family + IoT + Media + Guest | NAT redirect rules to `LOCAL_DNS:53` exist on `lan`, `opt2`, `opt3`, `opt4`, `opt5`, `opt6` | `config-pfSense.home.arpa-20260321225944.xml` (`<nat>`) | High |
| Office has DNS redirect exception for reverse proxy host | Office NAT rule source excludes `CADDY_HOST` | `config-pfSense.home.arpa-20260321225944.xml` (`<nat>`) | High |
| Family and Media have explicit reverse-proxy access rule | TCP pass rules from Family/Media to reverse proxy host (`CADDY_HOST`) | `config-pfSense.home.arpa-20260321225944.xml` (`<filter>`) | High |
| IoT and Guest are isolated from other private networks except explicit rules | `Block access to other networks` (RFC1918) + own-subnet + DNS + internet pass ordering | `config-pfSense.home.arpa-20260321225944.xml` (`<filter>`) | High |
| Core infrastructure static mappings on LAN exist | USW Lite 8, Mac mini, U6 LR, and TL-SG1016DE have static mappings on LAN | `config-pfSense.home.arpa-20260321225944.xml` (`<dhcpd><lan>`) | High |
| Caddy and DS920+ are statically mapped on Office VLAN | Reverse proxy (`10.10.0.5`) and DS920+ (`10.10.0.24`) mapped in Office subnet example | `config-pfSense.home.arpa-20260321225944.xml` (`<dhcpd><opt2>`) | High |
| Published reverse-proxy naming uses safe domain examples | `home.example.com` in templates | `.env.sample`, `caddy/Caddyfile_template` | High |
## 2. Device Inventory
| Device / Group | Role | Verified details |
|---|---|---|
| Calix GigaPoint 803G GPON ONT | ISP optical termination | From user topology (not repo-verified) |
| Netgate 1100 (pfSense) | Router/firewall, VLAN gateway, policy enforcement | VLAN names/CIDRs and policy behavior are documented in `dns/*` runbooks |
| Ubiquiti UB-USW-LITE-8-POE | Core aggregation switch after pfSense | From user topology (not repo-verified) |
| UniFi U6 LR AP | Managed Wi-Fi AP distributing VLAN-tagged SSIDs/traffic | From user topology (not repo-verified) |
| TP-Link TL-SG108 (unmanaged) | Media switch segment | From user topology (not repo-verified) |
| TP-Link TL-SG1016DE (managed) | Office/homelab switch segment | From user topology (not repo-verified) |
| Raspberry Pi 4 Model B (2GB) | DNS/ad-block host in AdBlock VLAN | Pi 4 2GB DNS deployment documented in `dns/technitium-deployment.md`; resolver IP `10.60.0.5` documented in `dns/*` |
| Mac mini | Endpoint connected to core switch | From user topology (not repo-verified) |
| Intel NUC | Homelab endpoint on office/homelab switch | From user topology (not repo-verified) |
| Synology DS920+ | NAS/homelab service host | Repo is Synology-focused; Caddy template maps `nas` to Office subnet prefix (`10.10.0.24:5000`) |
| Wireless family devices | Family VLAN clients | From user topology |
| Guest devices | Guest VLAN clients | From user topology |
| IoT devices | IoT VLAN clients | From user topology |
| Media devices (Samsung TV, Apple TV, soundbar, etc.) | Media VLAN clients | From user topology |
| Calix GigaPoint 803G GPON ONT | ISP optical termination | User topology source |
| Netgate 1100 (pfSense) | Router/firewall, inter-VLAN routing, NAT/policy | VLAN interfaces, NAT, aliases, and filter rules verified in pfSense backup |
| Ubiquiti UB-USW-LITE-8-POE | Core aggregation switch | Static mapping on LAN as `10.1.0.5` example |
| UniFi U6 LR (managed AP) | Multi-VLAN wireless AP | Static mapping on LAN as `10.1.0.7` example |
| TP-Link TL-SG108 (unmanaged) | Media downstream switch | User topology source (no direct pfSense static mapping expected) |
| TP-Link TL-SG1016DE (managed) | Office/homelab downstream switch | Static mapping on LAN as `10.1.0.8` example |
| Raspberry Pi 4 Model B (2GB) | Technitium DNS/ad-block host | Static mapping `dns01` on AdBlock VLAN as `10.60.0.5` example |
| Mac mini | Endpoint on core switch/LAN | Static mapping on LAN as `10.1.0.6` example |
| Intel NUC | Homelab endpoint | User-confirmed static IP on Office VLAN (public-safe value not published here) |
| Synology DS920+ | NAS/homelab service host | Static mapping in Office VLAN as `10.10.0.24` example |
| Office reverse proxy host (Caddy) | Controlled cross-VLAN ingress target | Alias `CADDY_HOST`; static mapping in Office VLAN as `10.10.0.5` example |
| Family/Guest/IoT wireless clients | Client groups on AP | Family and other client DHCP scopes verified |
| Media clients | TV/Apple TV/soundbar class clients | Media VLAN DHCP scope and static TV entry verified |
## 3. Physical Topology
Physical path (left-to-right):
1. Internet (500/500 Mbps fiber)
2. Calix GigaPoint 803G ONT
3. Netgate 1100 running pfSense
1. Internet (fibre)
2. Calix ONT
3. Netgate 1100 / pfSense
4. Ubiquiti UB-USW-LITE-8-POE (core switch)
5. Downstream from core switch:
- UniFi U6 LR managed AP (PoE, VLAN distribution)
- UniFi U6 LR managed AP (PoE)
- TP-Link TL-SG108 (media segment)
- TP-Link TL-SG1016DE (office/homelab segment)
- Mac mini
- Raspberry Pi 4 (AdBlock VLAN; DNS/ad blocker)
- Raspberry Pi 4 (Technitium DNS)
6. Downstream endpoints:
- Media clients from TL-SG108
- Intel NUC, Synology DS920+, and other office/homelab devices from TL-SG1016DE
- Wireless clients (Family/Guest/IoT emphasis) via U6 LR
- Media clients via TL-SG108
- Office/homelab endpoints via TL-SG1016DE (including DS920+, other infra)
- Wireless Family/Guest/IoT clients via U6 LR
Physical/logical clarification:
- Raspberry Pi DNS host is physically connected to switching.
- pfSense-to-DNS is a routed logical resolver path, not a direct cable.
Netgate internal switch implementation details are intentionally abstracted in this public-safe document.
## 4. Logical Topology / VLAN Layout
| VLAN | Purpose | CIDR | Typical residents |
| VLAN | Purpose | CIDR (public-safe) | Typical residents |
|---|---|---|---|
| Office | Admin/workstation + homelab management zone | `10.10.0.0/24` (repo) | Caddy/reverse proxy host (`10.10.0.5`), NAS/services, office devices |
| Family | Family user traffic, controlled access to office reverse proxy | `10.20.0.0/24` (repo) | Family wireless clients |
| IoT | Device isolation segment | `10.30.0.0/24` (repo) | IoT clients |
| Media | Media endpoint segment with controlled access to office reverse proxy | `10.40.0.0/24` (repo) | TV/Apple TV/soundbar/media devices |
| Guest | Guest client isolation segment | `10.50.0.0/24` (repo) | Guest devices |
| AdBlock | Central DNS/ad-blocking services | `10.60.0.0/24` (repo) | Raspberry Pi DNS/ad-block node (`10.60.0.5` in repo docs) |
| LAN | Additional local segment referenced by pfSense docs | `10.1.0.0/24` (repo) | LAN services and gateway path |
Notes:
- CIDRs above are repo-documented in pfSense/DNS runbooks.
- Domain values in templates use `home.example.com` defaults; production domain is not confirmed in repo.
| LAN | Core local management/client segment | `10.1.0.0/24` | Switch/AP management, Mac mini, baseline LAN clients |
| Office | Admin/workstation + homelab services | `10.10.0.0/24` | Caddy reverse proxy, DS920+, Proxmox-related services |
| Family | Family user segment | `10.20.0.0/24` | Family wireless devices |
| IoT | IoT isolation segment | `10.30.0.0/24` | IoT clients |
| Media | Media device segment | `10.40.0.0/24` | TV/media devices |
| Guest | Guest isolation segment | `10.50.0.0/24` | Guest clients |
| AdBlock | Central DNS/ad-block services | `10.60.0.0/24` | Technitium DNS host |
## 5. Access Policy Summary
### Plain-language policy intent
- Office: full internal access to itself, LAN, and all VLANs.
- Family: access to itself plus Office reverse proxy destination only.
- IoT: self-only.
- Media: access to itself plus Office reverse proxy destination only.
- Guest: self-only.
- AdBlock: access to all VLANs including LAN.
### Plain-language policy (current pfSense backup)
- LAN: default allow to any; DNS redirect present.
- Office: broad access policy (allow any); DNS redirect present with `CADDY_HOST` source exception.
- Family: allow own subnet, allow TCP to Office reverse proxy, allow DNS to resolver, block other RFC1918, then allow internet.
- IoT: allow own subnet, allow DNS to resolver, block other RFC1918, then allow internet.
- Media: allow own subnet, allow TCP to Office reverse proxy, allow DNS to resolver, block other RFC1918, then allow internet.
- Guest: allow own subnet, allow DNS to resolver, block other RFC1918, then allow internet.
- AdBlock: broad allow policy (pass any).
### Compact matrix (intent)
| Source VLAN | Self | LAN | Office (general) | Office reverse proxy | Family | IoT | Media | Guest | AdBlock |
|---|---|---|---|---|---|---|---|---|---|
| Office | Allow | Allow | Allow | Allow | Allow | Allow | Allow | Allow | Allow |
| Family | Allow | Deny | Deny | Allow | Deny | Deny | Deny | Deny | Allow (DNS path expected) |
| IoT | Allow | Deny | Deny | Deny | Deny | Deny | Deny | Deny | Allow (DNS path expected) |
| Media | Allow | Deny | Deny | Allow | Deny | Deny | Deny | Deny | Allow (DNS path expected) |
| Guest | Allow | Deny | Deny | Deny | Deny | Deny | Deny | Deny | Allow (DNS path expected) |
| AdBlock | Allow | Allow | Allow | N/A | Allow | Allow | Allow | Allow | Allow |
AdBlock tightening guidance:
- Current behavior is functional and intentionally permissive.
- If you want tighter posture later, start with least-disruptive controls:
- Allow required flows only (DNS, upstream resolver access, update traffic, and admin access from Office).
- Then deny broad east-west traffic from AdBlock to unrelated internal subnets.
Policy traceability:
- Intent rows come from the user brief.
- DNS exceptions are supported by repo pfSense runbooks that explicitly permit/redirect DNS to `10.60.0.5`.
### Recommended `OPT7` Rule Order (Moderate)
This order is for the **AdBlock interface rules** (top to bottom), using sanitized public-safe values.
Required aliases:
- `LOCAL_DNS` = `10.60.0.5`
- `PFSENSE_DNS` = `10.1.0.1` (create this if you use pfSense as Technitium upstream)
- `RFC1918` (already present in your config)
Rule order:
| # | Action | Source | Destination | Protocol/Port | Purpose |
|---|---|---|---|---|---|
| 1 | Pass | `LOCAL_DNS` | `PFSENSE_DNS` | TCP/UDP 53 | Use when Technitium forwards to pfSense |
| 2 | Pass | `LOCAL_DNS` | `!RFC1918` | TCP/UDP 53 | Use when Technitium does direct recursion |
| 3 | Pass | `LOCAL_DNS` | `!RFC1918` | TCP 443 (optional 80) | Blocklist/package/update access |
| 4 | Pass | `LOCAL_DNS` | `!RFC1918` | UDP 123 | Time sync (NTP) |
| 5 | Block (log) | `OPT7 net` | `RFC1918` | any | Prevent broad lateral movement to internal subnets |
| 6 | Remove/disable broad pass | `OPT7 net` | `any` | any | Replace current permissive `pass any` stance |
Operational notes:
- Keep **either Rule 1 or Rule 2** depending on your Technitium upstream mode.
- Client-to-DNS access remains controlled on client VLAN interfaces (LAN/Office/Family/IoT/Media/Guest), so tightening `OPT7` does not inherently break client DNS.
- Apply changes during a low-risk window and test from each VLAN after each step.
### Compact matrix (sanitized)
| Source VLAN | Own Subnet | Other Private Subnets (RFC1918) | Office Reverse Proxy | DNS Resolver (`10.60.0.5`) | Internet |
|---|---|---|---|---|---|
| LAN | Allow | Allow | Allow | Force-redirect/allow | Allow |
| Office | Allow | Allow | Allow | Force-redirect with `CADDY_HOST` exception | Allow |
| Family | Allow | Deny (except explicit allows) | Allow (TCP) | Force-redirect/allow | Allow |
| IoT | Allow | Deny (except explicit DNS) | Deny | Force-redirect/allow | Allow |
| Media | Allow | Deny (except explicit allows) | Allow (TCP) | Force-redirect/allow | Allow |
| Guest | Allow | Deny (except explicit DNS) | Deny | Force-redirect/allow | Allow |
| AdBlock | Allow | Allow | Allow | N/A (hosting resolver) | Allow |
## 6. Wireless and Media Segmentation
- UniFi U6 LR is the wireless entry point carrying multiple VLANs, with practical emphasis on Family, Guest, and IoT traffic per user topology.
- Media devices are grouped behind TP-Link TL-SG108 (unmanaged), treated as Media VLAN clients in the logical model.
- Office/homelab infrastructure is grouped behind TP-Link TL-SG1016DE (managed) for Intel NUC, Synology DS920+, and related systems.
- UniFi U6 LR is managed and distributes VLAN-backed wireless client traffic.
- Family/Guest/IoT traffic is primarily represented as Wi-Fi client groups behind the AP.
- Media devices are grouped behind TP-Link TL-SG108.
- Office/homelab infrastructure is grouped behind TP-Link TL-SG1016DE.
## 7. DNS / Ad-Blocking Path
Verified flow from repo docs:
1. Clients receive DNS settings that point to resolver IP `10.60.0.5` (pfSense + DNS runbook docs).
2. DNS/ad-block service runs in the AdBlock VLAN (`10.60.0.0/24`) on Raspberry Pi-hosted stack (Pi-hole current, Technitium target).
3. Local split DNS maps reverse-proxied app names toward the Office-hosted reverse proxy (`caddy.home.example.com` -> `10.10.0.5`).
Repo-derived details:
- Resolver IP: `10.60.0.5`
- Reverse proxy DNS anchor: `caddy.home.example.com`
- Upstream strategy references include forwarding via pfSense (`10.1.0.1`) or direct recursion (migration option)
- Blocklist reference: StevenBlack hosts list
Current-state flow (sanitized):
1. DHCP hands clients resolver `10.60.0.5` on LAN + Office + Family + IoT + Media + Guest.
2. pfSense NAT redirects port 53 traffic to `LOCAL_DNS` on LAN + Office + Family + IoT + Media + Guest.
3. Office redirect rule excludes `CADDY_HOST` source to avoid ACME DNS-01 resolution issues.
4. `LOCAL_DNS` alias points to Technitium on AdBlock VLAN (`10.60.0.5`).
5. AdBlock host (`dns01`) is statically mapped to the resolver IP.
## 8. Reverse Proxy Notes
Repo-verified reverse proxy context:
- Caddy config template defines many internal service hostnames under `{{CADDY_BASE_DOMAIN}}`.
- Office-hosted reverse proxy target is consistently represented as `10.10.0.5` in pfSense DNS runbooks.
- Caddy upstream targets include:
- `nas` -> `10.10.0.24:5000`
- `proxmox` -> `10.10.0.10:8006`
- `pbs` -> `10.10.0.8:8007`
- multiple media/app services on office subnet hosts
Important domain caveat:
- Repo templates/defaults use `home.example.com`.
- `home.brianpooe.com` was not found in this repository.
- Reverse proxy host is represented as `10.10.0.5` in public-safe docs.
- `CADDY_HOST` alias is used by pfSense policy and DNS redirect exception logic.
- Family and Media have explicit TCP allow rules to reverse proxy destination.
- Published hostnames remain under `home.example.com` in repository templates.
## 9. Assumptions / Unknowns
1. Physical hardware chain is treated as authoritative from user brief because repo does not include hardware inventory files for ONT/switch/AP/endpoint cabling.
2. No switch port assignments, trunk/access mode per port, or VLAN tagging maps were found.
3. No SSIDs, Wi-Fi security settings, or AP radio policy details were found.
4. No definitive production base domain value was found (only template default `home.example.com`).
5. pfSense runbook docs indicate current-state DNS NAT redirect is LAN-only in one analysis, while other runbooks define desired all-VLAN forced DNS; active state at this moment is not directly verifiable from this repo alone.
6. IPs for Mac mini, Intel NUC, DS920+, and most endpoints are not directly verified in repo.
7. Firewall rule IDs/order numbers are not provided in repo; only intent and runbook-level policy are documented.
1. TL-SG108 is unmanaged; no dedicated management IP is visible in pfSense DHCP static maps (you indicated this was removed accidentally and will be added back).
2. Downstream switch port-by-port access/trunk assignments are intentionally abstracted in public docs.
3. SSID names, WLAN security settings, and AP radio policy are not stored in this repo.
4. It is not confirmed whether `drawio` service (`... .9:8080` in template form) is currently active in production.
5. AdBlock VLAN is intentionally broad right now; future hardening boundaries are a policy decision.
## 10. Validation Checklist
Use this quick checklist to close remaining gaps:
1. Confirm production domain: is internal DNS/reverse proxy domain still `home.example.com`, or another value (for example `home.brianpooe.com`)?
2. Confirm active pfSense state: are forced DNS NAT rules currently active on LAN only, or LAN + Office/Family/IoT/Media/Guest?
3. Confirm reverse proxy host placement: is Caddy currently at `10.10.0.5` on Office VLAN?
4. Confirm DNS resolver host/IP: is Raspberry Pi 4 (2GB) currently serving DNS at `10.60.0.5`?
5. Confirm whether IoT and Guest are strict self-only or self-only plus DNS exception to AdBlock VLAN.
6. Confirm switch uplink/trunk and access-port mappings (USW Lite 8 PoE, TL-SG108, TL-SG1016DE).
7. Confirm endpoint IPs/hostnames for Mac mini, Intel NUC, Synology DS920+ for diagram annotations.
8. Confirm whether any direct LAN segment clients/services should be drawn explicitly beyond VLAN interfaces.
1. Confirm your preferred AdBlock hardening level: `Current`, `Moderate`, or `Strict`.
2. Confirm when TL-SG108 management IP/static map is re-added so docs can include it.
3. Confirm whether Technitium upstream mode is `Forward-to-pfSense` or `Direct recursion` (drives OPT7 Rule 1 vs Rule 2).
4. Confirm whether `drawio` upstream at Office `.9:8080` should stay in templates (diagram currently omits service nodes by request).