ADR-0017: add network topology diagram (SVG) next to the decision
All checks were successful
ci/woodpecker/push/default Pipeline was successful
All checks were successful
ci/woodpecker/push/default Pipeline was successful
Viktor asked for a reviewable network visualization committed alongside the CCTV-segment ADR. Hand-drawn SVG (renders on Forgejo, validated palette): physical path camera -> TL-SG105PE port-VLANs -> eno2/vmbr2 -> pfSense dCCTV, the firewall flows (Frigate RTSP, ha-sofia ISAPI/RTSP, NTP-only egress, default deny), and the dashed camera-day steps (patch cable, cat6 run, AX6000 static route). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
248e186dce
commit
b761701994
2 changed files with 198 additions and 0 deletions
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
Status: accepted (2026-07-02)
|
||||
|
||||

|
||||
|
||||
The first owned camera at the Sofia/Vermont site (`vermont-garage`, HiLook
|
||||
IPC-T241H-C at the garage entrance) needs to be network-isolated: its cable is
|
||||
physically exposed outside the apartment, so anything plugged into that cable
|
||||
|
|
|
|||
196
docs/adr/0017-cctv-segment-topology.svg
Normal file
196
docs/adr/0017-cctv-segment-topology.svg
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="880" viewBox="0 0 1600 880" font-family="system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif">
|
||||
<!-- ADR-0017 dCCTV topology. Colors: reference dataviz palette (light mode).
|
||||
blue #2a78d6 = home LAN / VLAN1 · violet #4a3aa7 = dCCTV / VLAN30 ·
|
||||
aqua #1baf7a = dKubernetes · yellow #eda100 = dManagementsVms ·
|
||||
green #008300 = allowed flow · red #e34948 = denied flow -->
|
||||
<defs>
|
||||
<marker id="arrGreen" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M0,0 L10,5 L0,10 z" fill="#008300"/>
|
||||
</marker>
|
||||
<marker id="arrRed" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M0,0 L10,5 L0,10 z" fill="#e34948"/>
|
||||
</marker>
|
||||
<marker id="arrGray" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
|
||||
<path d="M0,0 L10,5 L0,10 z" fill="#52514e"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<rect width="1600" height="880" fill="#fcfcfb"/>
|
||||
|
||||
<!-- title -->
|
||||
<text x="40" y="42" font-size="26" font-weight="700" fill="#0b0b0b">ADR-0017 — CCTV segment on a dedicated pfSense leg</text>
|
||||
<text x="40" y="66" font-size="15" fill="#52514e">Sofia/Vermont · as-built 2026-07-02 · dashed = camera-day · untagged on every wire</text>
|
||||
|
||||
<!-- camera -> everything else (denied): kept above the zones, below the subtitle -->
|
||||
<path d="M240,168 C520,104 900,104 1148,140" fill="none" stroke="#e34948" stroke-width="3" marker-end="url(#arrRed)"/>
|
||||
<g transform="translate(560,111)">
|
||||
<circle r="11" fill="#fcfcfb" stroke="#e34948" stroke-width="2.5"/>
|
||||
<path d="M-5,-5 L5,5 M5,-5 L-5,5" stroke="#e34948" stroke-width="2.5"/>
|
||||
</g>
|
||||
<text x="588" y="100" font-size="13.5" font-weight="700" fill="#e34948">DENY · camera → LAN / other segments / internet (default deny on dCCTV)</text>
|
||||
|
||||
<!-- ═════════ GARAGE ENTRANCE zone ═════════ -->
|
||||
<rect x="40" y="128" width="240" height="180" rx="10" fill="#4a3aa7" fill-opacity="0.06" stroke="#4a3aa7" stroke-opacity="0.35"/>
|
||||
<text x="56" y="154" font-size="13" font-weight="700" fill="#52514e" letter-spacing="1">GARAGE ENTRANCE</text>
|
||||
<rect x="64" y="170" width="192" height="112" rx="8" fill="#ffffff" stroke="#4a3aa7" stroke-width="2"/>
|
||||
<text x="80" y="196" font-size="15" font-weight="700" fill="#0b0b0b">vermont-garage</text>
|
||||
<text x="80" y="216" font-size="12.5" fill="#52514e">HiLook IPC-T241H-C · pure IR</text>
|
||||
<text x="80" y="234" font-size="12.5" fill="#52514e">10.0.30.70 (Kea reservation)</text>
|
||||
<text x="80" y="252" font-size="12.5" fill="#52514e">DNS: garage-cam.viktorbarzin.lan</text>
|
||||
<text x="80" y="270" font-size="12.5" fill="#52514e">PoE from switch · cloud/P2P off</text>
|
||||
|
||||
<!-- camera cable to switch P4 (camera day, dashed) -->
|
||||
<path d="M160,308 L160,352" fill="none" stroke="#52514e" stroke-width="2" stroke-dasharray="6,5" marker-end="url(#arrGray)"/>
|
||||
<text x="172" y="334" font-size="12" fill="#52514e">cat6 in conduit · PoE</text>
|
||||
|
||||
<!-- ═════════ RACK zone ═════════ -->
|
||||
<rect x="40" y="360" width="560" height="240" rx="10" fill="#0b0b0b" fill-opacity="0.03" stroke="#b9b8b2"/>
|
||||
<text x="56" y="386" font-size="13" font-weight="700" fill="#52514e" letter-spacing="1">RACK — GARAGE</text>
|
||||
|
||||
<!-- TL-SG105PE -->
|
||||
<rect x="64" y="400" width="512" height="176" rx="8" fill="#ffffff" stroke="#8a8984"/>
|
||||
<text x="80" y="426" font-size="15" font-weight="700" fill="#0b0b0b">TL-SG105PE</text>
|
||||
<text x="185" y="426" font-size="12.5" fill="#52514e">shared PoE switch · mgmt 192.168.1.6 (VLAN 1, Kea)</text>
|
||||
<text x="80" y="446" font-size="12.5" fill="#52514e">port-based VLANs, everything untagged</text>
|
||||
|
||||
<!-- ports row -->
|
||||
<g font-size="11.5" text-anchor="middle">
|
||||
<rect x="80" y="462" width="88" height="64" rx="6" fill="#2a78d6" fill-opacity="0.12" stroke="#2a78d6"/>
|
||||
<text x="124" y="482" font-weight="700" fill="#0b0b0b">P1 · VLAN 1</text>
|
||||
<text x="124" y="500" fill="#52514e">home-LAN</text>
|
||||
<text x="124" y="516" fill="#52514e">uplink</text>
|
||||
|
||||
<rect x="178" y="462" width="88" height="64" rx="6" fill="#2a78d6" fill-opacity="0.12" stroke="#2a78d6"/>
|
||||
<text x="222" y="482" font-weight="700" fill="#0b0b0b">P2 · VLAN 1</text>
|
||||
<text x="222" y="500" fill="#52514e">4G router</text>
|
||||
<text x="222" y="516" fill="#52514e">192.168.1.7</text>
|
||||
|
||||
<rect x="276" y="462" width="88" height="64" rx="6" fill="#2a78d6" fill-opacity="0.12" stroke="#2a78d6"/>
|
||||
<text x="320" y="482" font-weight="700" fill="#0b0b0b">P3 · VLAN 1</text>
|
||||
<text x="320" y="500" fill="#52514e">UPS mgmt</text>
|
||||
|
||||
<rect x="374" y="462" width="88" height="64" rx="6" fill="#4a3aa7" fill-opacity="0.12" stroke="#4a3aa7" stroke-width="2"/>
|
||||
<text x="418" y="482" font-weight="700" fill="#0b0b0b">P4 · VLAN 30</text>
|
||||
<text x="418" y="500" fill="#52514e">camera</text>
|
||||
<text x="418" y="516" fill="#52514e">PoE ON</text>
|
||||
|
||||
<rect x="472" y="462" width="88" height="64" rx="6" fill="#4a3aa7" fill-opacity="0.12" stroke="#4a3aa7" stroke-width="2"/>
|
||||
<text x="516" y="482" font-weight="700" fill="#0b0b0b">P5 · VLAN 30</text>
|
||||
<text x="516" y="500" fill="#52514e">uplink to</text>
|
||||
<text x="516" y="516" fill="#52514e">R730 eno2</text>
|
||||
</g>
|
||||
<text x="80" y="556" font-size="12" fill="#52514e">backup-WAN path (pfSense 4g_router gateway) and UPS ride VLAN 1 — untouched</text>
|
||||
|
||||
<!-- P5 -> eno2 cable (camera day, dashed) -->
|
||||
<path d="M560,494 C620,494 620,494 676,494" fill="none" stroke="#52514e" stroke-width="2" stroke-dasharray="6,5" marker-end="url(#arrGray)"/>
|
||||
<text x="575" y="482" font-size="12" fill="#52514e">patch</text>
|
||||
|
||||
<!-- P1 -> home LAN (existing uplink) -->
|
||||
<path d="M124,462 C124,336 940,300 1150,296" fill="none" stroke="#2a78d6" stroke-width="2" opacity="0.6"/>
|
||||
<text x="560" y="292" font-size="12" fill="#2a78d6">existing home-LAN uplink (VLAN 1)</text>
|
||||
|
||||
<!-- ═════════ R730 / PVE zone ═════════ -->
|
||||
<rect x="680" y="330" width="880" height="440" rx="10" fill="#0b0b0b" fill-opacity="0.03" stroke="#b9b8b2"/>
|
||||
<text x="696" y="356" font-size="13" font-weight="700" fill="#52514e" letter-spacing="1">DELL R730 — PVE HOST 192.168.1.127 (IN THE RACK)</text>
|
||||
|
||||
<!-- NIC/bridge chips on left edge -->
|
||||
<g font-size="12">
|
||||
<rect x="700" y="400" width="150" height="46" rx="6" fill="#2a78d6" fill-opacity="0.12" stroke="#2a78d6"/>
|
||||
<text x="712" y="419" font-weight="700" fill="#0b0b0b">eno1 → vmbr0</text>
|
||||
<text x="712" y="436" fill="#52514e">LAN1 · vlan-aware</text>
|
||||
|
||||
<rect x="700" y="471" width="150" height="46" rx="6" fill="#4a3aa7" fill-opacity="0.12" stroke="#4a3aa7" stroke-width="2"/>
|
||||
<text x="712" y="490" font-weight="700" fill="#0b0b0b">eno2 → vmbr2</text>
|
||||
<text x="712" y="507" fill="#52514e">NEW · dedicated leg</text>
|
||||
|
||||
<rect x="700" y="542" width="150" height="46" rx="6" fill="#0b0b0b" fill-opacity="0.04" stroke="#8a8984"/>
|
||||
<text x="712" y="561" font-weight="700" fill="#0b0b0b">vmbr1</text>
|
||||
<text x="712" y="578" fill="#52514e">internal · tags 10/20</text>
|
||||
</g>
|
||||
|
||||
<!-- pfSense VM -->
|
||||
<rect x="890" y="388" width="300" height="230" rx="8" fill="#ffffff" stroke="#8a8984"/>
|
||||
<text x="906" y="414" font-size="15" font-weight="700" fill="#0b0b0b">pfSense (VM 101)</text>
|
||||
<text x="906" y="432" font-size="12" fill="#52514e">gateway + firewall for every segment</text>
|
||||
<g font-size="12">
|
||||
<rect x="906" y="444" width="268" height="34" rx="5" fill="#2a78d6" fill-opacity="0.12" stroke="#2a78d6"/>
|
||||
<text x="916" y="465" fill="#0b0b0b">net0 · WAN <tspan fill="#52514e">192.168.1.2 (home LAN)</tspan></text>
|
||||
<rect x="906" y="484" width="268" height="34" rx="5" fill="#eda100" fill-opacity="0.14" stroke="#eda100"/>
|
||||
<text x="916" y="505" fill="#0b0b0b">net1 · dManagementsVms <tspan fill="#52514e">10.0.10.1</tspan></text>
|
||||
<rect x="906" y="524" width="268" height="34" rx="5" fill="#1baf7a" fill-opacity="0.12" stroke="#1baf7a"/>
|
||||
<text x="916" y="545" fill="#0b0b0b">net2 · dKubernetes <tspan fill="#52514e">10.0.20.1</tspan></text>
|
||||
<rect x="906" y="564" width="268" height="34" rx="5" fill="#4a3aa7" fill-opacity="0.12" stroke="#4a3aa7" stroke-width="2"/>
|
||||
<text x="916" y="585" fill="#0b0b0b">net3 · dCCTV <tspan fill="#52514e">10.0.30.1/24 · NEW</tspan></text>
|
||||
</g>
|
||||
<!-- bridge attachments -->
|
||||
<path d="M850,423 L890,458" fill="none" stroke="#2a78d6" stroke-width="1.6" opacity="0.6"/>
|
||||
<path d="M850,494 L890,581" fill="none" stroke="#4a3aa7" stroke-width="2"/>
|
||||
<path d="M850,565 L890,501" fill="none" stroke="#8a8984" stroke-width="1.6" opacity="0.6"/>
|
||||
<path d="M850,565 L890,541" fill="none" stroke="#8a8984" stroke-width="1.6" opacity="0.6"/>
|
||||
|
||||
<!-- k8s VMs -->
|
||||
<rect x="1240" y="388" width="290" height="230" rx="8" fill="#1baf7a" fill-opacity="0.07" stroke="#1baf7a"/>
|
||||
<text x="1256" y="414" font-size="15" font-weight="700" fill="#0b0b0b">k8s VMs · 10.0.20.0/24</text>
|
||||
<text x="1256" y="434" font-size="12.5" fill="#52514e">vmbr1 tag 20 · pod egress SNATs</text>
|
||||
<text x="1256" y="450" font-size="12.5" fill="#52514e">to node IPs</text>
|
||||
<rect x="1256" y="464" width="258" height="66" rx="6" fill="#ffffff" stroke="#1baf7a"/>
|
||||
<text x="1268" y="486" font-size="13.5" font-weight="700" fill="#0b0b0b">Frigate · k8s-node1 (T4)</text>
|
||||
<text x="1268" y="504" font-size="12" fill="#52514e">detect sub / record main</text>
|
||||
<text x="1268" y="520" font-size="12" fill="#52514e">gpumem budget 2300 MiB</text>
|
||||
<rect x="1256" y="540" width="258" height="52" rx="6" fill="#ffffff" stroke="#1baf7a"/>
|
||||
<text x="1268" y="562" font-size="13.5" font-weight="700" fill="#0b0b0b">go2rtc LB 10.0.20.204</text>
|
||||
<text x="1268" y="580" font-size="12" fill="#52514e">restream → HA live view (MSE/HLS)</text>
|
||||
|
||||
<!-- ═════════ HOME LAN zone ═════════ -->
|
||||
<rect x="1148" y="128" width="412" height="180" rx="10" fill="#2a78d6" fill-opacity="0.06" stroke="#2a78d6" stroke-opacity="0.4"/>
|
||||
<text x="1164" y="154" font-size="13" font-weight="700" fill="#52514e" letter-spacing="1">HOME LAN 192.168.1.0/24 (VLAN 1)</text>
|
||||
<rect x="1164" y="168" width="180" height="56" rx="6" fill="#ffffff" stroke="#2a78d6"/>
|
||||
<text x="1176" y="190" font-size="13.5" font-weight="700" fill="#0b0b0b">AX6000 · .1</text>
|
||||
<text x="1176" y="208" font-size="11.5" fill="#52514e">+ route 10.0.30.0/24 → .2</text>
|
||||
<rect x="1164" y="236" width="180" height="52" rx="6" fill="#ffffff" stroke="#2a78d6"/>
|
||||
<text x="1176" y="258" font-size="13.5" font-weight="700" fill="#0b0b0b">ha-sofia · .8</text>
|
||||
<text x="1176" y="275" font-size="11.5" fill="#52514e">Frigate card + hikvision_next</text>
|
||||
<rect x="1360" y="168" width="184" height="56" rx="6" fill="#ffffff" stroke="#2a78d6"/>
|
||||
<text x="1372" y="190" font-size="13.5" font-weight="700" fill="#0b0b0b">SW1 + clients</text>
|
||||
<text x="1372" y="208" font-size="11.5" fill="#52514e">laptops, R730 eno1 uplink</text>
|
||||
<!-- AX6000 route badge (camera day) -->
|
||||
<rect x="1360" y="236" width="184" height="52" rx="6" fill="#ffffff" stroke="#52514e" stroke-dasharray="5,4"/>
|
||||
<text x="1372" y="256" font-size="11.5" font-weight="700" fill="#52514e">CAMERA DAY: static route</text>
|
||||
<text x="1372" y="272" font-size="11.5" fill="#52514e">10.0.30.0/24 via 192.168.1.2</text>
|
||||
|
||||
<!-- home LAN -> eno1 -->
|
||||
<path d="M1254,308 C1150,352 950,372 790,400" fill="none" stroke="#2a78d6" stroke-width="2" opacity="0.6"/>
|
||||
|
||||
<!-- ═════════ FLOWS ═════════ -->
|
||||
<!-- Frigate -> camera RTSP (allowed): sweeps under the rack, terminates at the camera box -->
|
||||
<path d="M1256,497 C1010,680 330,720 120,640 C40,608 40,380 96,286" fill="none" stroke="#008300" stroke-width="3" marker-end="url(#arrGreen)"/>
|
||||
<text x="560" y="688" font-size="13.5" font-weight="700" fill="#008300">ALLOW · Frigate → camera RTSP :554 (routed k8s → dCCTV; opt1 allow-all)</text>
|
||||
|
||||
<!-- HA -> camera (allowed, via AX6000 route + WAN rules): labels above, arc dips below them -->
|
||||
<path d="M1164,262 C820,282 470,268 302,176 C286,167 278,166 270,172" fill="none" stroke="#008300" stroke-width="3" marker-end="url(#arrGreen)"/>
|
||||
<text x="484" y="216" font-size="13.5" font-weight="700" fill="#008300">ALLOW · ha-sofia → camera :80 ISAPI + :554</text>
|
||||
<text x="484" y="234" font-size="12" fill="#52514e">enters pfSense WAN · reply-to off · needs the AX6000 route</text>
|
||||
|
||||
<!-- camera -> NTP (allowed) -->
|
||||
<path d="M280,232 C660,200 860,320 936,386" fill="none" stroke="#008300" stroke-width="2" opacity="0.85" marker-end="url(#arrGreen)"/>
|
||||
<text x="740" y="322" font-size="12.5" font-weight="700" fill="#008300">ALLOW · camera → 10.0.30.1:123 (NTP)</text>
|
||||
|
||||
<!-- ═════════ LEGEND ═════════ -->
|
||||
<g transform="translate(40,800)" font-size="12.5">
|
||||
<rect x="0" y="0" width="18" height="18" rx="4" fill="#2a78d6" fill-opacity="0.12" stroke="#2a78d6"/>
|
||||
<text x="26" y="14" fill="#0b0b0b">home LAN / VLAN 1</text>
|
||||
<rect x="190" y="0" width="18" height="18" rx="4" fill="#4a3aa7" fill-opacity="0.12" stroke="#4a3aa7" stroke-width="2"/>
|
||||
<text x="216" y="14" fill="#0b0b0b">CCTV · VLAN 30 / dCCTV 10.0.30.0/24</text>
|
||||
<rect x="490" y="0" width="18" height="18" rx="4" fill="#1baf7a" fill-opacity="0.12" stroke="#1baf7a"/>
|
||||
<text x="516" y="14" fill="#0b0b0b">dKubernetes</text>
|
||||
<rect x="630" y="0" width="18" height="18" rx="4" fill="#eda100" fill-opacity="0.14" stroke="#eda100"/>
|
||||
<text x="656" y="14" fill="#0b0b0b">dManagementsVms</text>
|
||||
<line x1="810" y1="9" x2="850" y2="9" stroke="#008300" stroke-width="3" marker-end="url(#arrGreen)"/>
|
||||
<text x="860" y="14" fill="#0b0b0b">allowed flow</text>
|
||||
<line x1="970" y1="9" x2="1010" y2="9" stroke="#e34948" stroke-width="3" marker-end="url(#arrRed)"/>
|
||||
<text x="1020" y="14" fill="#0b0b0b">denied</text>
|
||||
<line x1="1090" y1="9" x2="1130" y2="9" stroke="#52514e" stroke-width="2" stroke-dasharray="6,5"/>
|
||||
<text x="1140" y="14" fill="#0b0b0b">camera-day step</text>
|
||||
<text x="1310" y="14" fill="#52514e">ADR-0017 · 2026-07-02</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 14 KiB |
Loading…
Add table
Add a link
Reference in a new issue