643 lines
31 KiB
HTML
643 lines
31 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Doris Network Redesign Plan</title>
|
|
<style>
|
|
:root{
|
|
color-scheme:dark;
|
|
--hf-red:#d53600;
|
|
--hf-red-deep:#910f3f;
|
|
--hf-amber:#f2c14e;
|
|
--hf-blue:#7b8fb2;
|
|
--bg:#090b10;
|
|
--bg-accent:#131824;
|
|
--panel:#11151d;
|
|
--panel-soft:#171d27;
|
|
--panel-raise:#1d2430;
|
|
--text:#f2efdd;
|
|
--muted:#cbbda7;
|
|
--line:rgba(242,239,221,.11);
|
|
--line-soft:rgba(242,239,221,.06);
|
|
--accent:var(--hf-red);
|
|
--warn:#ff7b72;
|
|
--ok:#82c29a;
|
|
--attention:#ffd166;
|
|
--shadow:0 20px 48px rgba(0,0,0,.34);
|
|
--radius:22px;
|
|
}
|
|
*{box-sizing:border-box}
|
|
html{scroll-behavior:smooth}
|
|
body{
|
|
margin:0;
|
|
font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
|
|
background:
|
|
radial-gradient(circle at top left,rgba(213,54,0,.22),transparent 24rem),
|
|
radial-gradient(circle at top right,rgba(123,143,178,.16),transparent 22rem),
|
|
linear-gradient(180deg,#07090d 0%,#0d1017 52%,#131824 100%);
|
|
color:var(--text);
|
|
}
|
|
a{color:inherit}
|
|
.incident-tape{height:14px;background:repeating-linear-gradient(135deg,var(--hf-amber) 0 18px,#111 18px 36px);box-shadow:0 3px 14px rgba(0,0,0,.32)}
|
|
main{max-width:1400px;margin:0 auto;padding:20px}
|
|
.hero,.panel,.vlan-card,.ssid-card,.phase-card,.matrix-card,.legend-card,.topology,.coverage-card{
|
|
background:rgba(17,21,29,.92);
|
|
border:1px solid var(--line);
|
|
box-shadow:var(--shadow);
|
|
border-radius:var(--radius);
|
|
}
|
|
.hero{
|
|
padding:22px;
|
|
display:grid;
|
|
grid-template-columns:1.4fr .9fr;
|
|
gap:16px;
|
|
position:relative;
|
|
overflow:hidden;
|
|
}
|
|
.hero:before{
|
|
content:"";
|
|
position:absolute;
|
|
inset:0;
|
|
background:
|
|
radial-gradient(circle at 82% 18%, rgba(213,54,0,.18), transparent 18rem),
|
|
radial-gradient(circle at 14% 10%, rgba(123,143,178,.16), transparent 16rem),
|
|
repeating-linear-gradient(0deg, rgba(255,255,255,.018) 0 2px, transparent 2px 5px);
|
|
pointer-events:none;
|
|
opacity:.5;
|
|
}
|
|
.eyebrow{margin:0 0 8px;color:var(--hf-amber);text-transform:uppercase;letter-spacing:.18em;font-size:.74rem}
|
|
h1{margin:0;font-size:clamp(2.3rem,5vw,4.1rem);line-height:.95;letter-spacing:-.04em}
|
|
.sub{margin:12px 0 0;color:var(--muted);max-width:68ch;line-height:1.5}
|
|
.hero-actions,.filters,.quick-links{display:flex;flex-wrap:wrap;gap:10px}
|
|
.pill,button.filter,button.toggle{
|
|
border:1px solid rgba(242,193,78,.26);
|
|
background:rgba(242,193,78,.12);
|
|
color:#ffe9b3;
|
|
border-radius:999px;
|
|
padding:8px 12px;
|
|
font-size:.83rem;
|
|
}
|
|
button.filter,button.toggle{cursor:pointer}
|
|
button.filter.active,button.toggle.active{background:rgba(213,54,0,.2);border-color:rgba(213,54,0,.45);color:#fff1e8}
|
|
.hero-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:16px}
|
|
.hero-stat{background:rgba(15,18,25,.9);border:1px solid rgba(242,239,221,.08);border-radius:18px;padding:14px}
|
|
.hero-stat strong{display:block;font-size:1.35rem}
|
|
.hero-stat small{display:block;color:var(--muted);margin-top:4px;line-height:1.35}
|
|
.stack{display:grid;gap:16px;margin-top:16px}
|
|
.panel{padding:18px}
|
|
.panel h2{margin:0 0 12px;font-size:1.25rem}
|
|
.section-head{display:flex;justify-content:space-between;align-items:flex-end;gap:12px;flex-wrap:wrap}
|
|
.section-head p{margin:0;color:var(--muted)}
|
|
.topology{padding:18px}
|
|
.topology-grid{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:12px;margin-top:14px;align-items:stretch}
|
|
.node{background:linear-gradient(180deg,rgba(255,255,255,.04),rgba(255,255,255,.015)),rgba(15,18,25,.96);border:1px solid rgba(242,239,221,.1);border-radius:18px;padding:14px;min-height:120px;position:relative}
|
|
.node small{display:block;color:var(--muted);margin-top:6px;line-height:1.35}
|
|
.node .tag{display:inline-block;margin-top:10px;padding:4px 8px;border-radius:999px;font-size:.72rem;border:1px solid var(--line)}
|
|
.node.current{outline:1px solid rgba(255,123,114,.3)}
|
|
.node.target{outline:1px solid rgba(130,194,154,.32)}
|
|
.arrow{display:flex;align-items:center;justify-content:center;color:var(--hf-amber);font-size:1.35rem}
|
|
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
|
|
.vlan-card,.ssid-card,.phase-card,.matrix-card,.legend-card,.coverage-card{padding:18px;position:relative}
|
|
.vlan-card h3,.ssid-card h3,.phase-card h3,.matrix-card h3,.coverage-card h3{margin:0 0 8px;font-size:1.1rem}
|
|
.meta{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px}
|
|
.chip{padding:5px 9px;border-radius:999px;font-size:.76rem;background:rgba(123,143,178,.15);border:1px solid rgba(123,143,178,.24)}
|
|
.chip.warn{background:rgba(255,123,114,.14);border-color:rgba(255,123,114,.28)}
|
|
.chip.ok{background:rgba(130,194,154,.15);border-color:rgba(130,194,154,.28)}
|
|
.chip.attention{background:rgba(242,193,78,.14);border-color:rgba(242,193,78,.28)}
|
|
ul{margin:10px 0 0 18px;padding:0}
|
|
li{margin:5px 0;color:#e4ddcf}
|
|
.muted{color:var(--muted)}
|
|
details{margin-top:12px;border-top:1px solid var(--line-soft);padding-top:10px}
|
|
summary{cursor:pointer;color:#ffe9b3}
|
|
.hidden-advanced .advanced{display:none !important}
|
|
.filter-hide{display:none !important}
|
|
.matrix{display:grid;grid-template-columns:1.2fr repeat(4,minmax(0,1fr));gap:1px;background:var(--line);border-radius:16px;overflow:hidden;margin-top:12px}
|
|
.cell{background:rgba(15,18,25,.96);padding:12px;font-size:.92rem;line-height:1.35}
|
|
.cell.head{background:rgba(123,143,178,.16);font-weight:700}
|
|
.coverage-layout{display:grid;grid-template-columns:1.1fr .9fr;gap:14px}
|
|
.floor-map{background:rgba(15,18,25,.96);border:1px solid var(--line-soft);border-radius:18px;padding:16px;min-height:280px;position:relative;overflow:hidden}
|
|
.floor{position:absolute;border:1px dashed rgba(242,239,221,.18);border-radius:18px;padding:10px;color:var(--muted)}
|
|
.floor.upstairs{left:20px;right:20px;top:20px;height:110px}
|
|
.floor.downstairs{left:20px;right:20px;bottom:20px;height:110px}
|
|
.ap{position:absolute;width:56px;height:56px;border-radius:50%;display:grid;place-items:center;font-weight:800;background:rgba(123,143,178,.22);border:1px solid rgba(123,143,178,.45);box-shadow:0 0 0 1px rgba(123,143,178,.1),0 0 45px rgba(123,143,178,.18)}
|
|
.ap.u7{top:48px;right:80px}
|
|
.ap.u6{bottom:52px;left:90px;background:rgba(242,193,78,.18);border-color:rgba(242,193,78,.45);box-shadow:0 0 0 1px rgba(242,193,78,.1),0 0 45px rgba(242,193,78,.18)}
|
|
.ap.off{opacity:.25;filter:grayscale(1)}
|
|
.coverage-zone{position:absolute;border-radius:999px;filter:blur(2px);opacity:.32}
|
|
.zone-u7{background:radial-gradient(circle, rgba(123,143,178,.82), transparent 70%);width:260px;height:180px;top:8px;right:8px}
|
|
.zone-u6{background:radial-gradient(circle, rgba(242,193,78,.82), transparent 70%);width:260px;height:180px;bottom:6px;left:8px}
|
|
.footer-note{margin-top:18px;color:var(--muted);font-size:.92rem}
|
|
.nav{display:flex;gap:10px;flex-wrap:wrap;margin:14px 0 0}
|
|
.nav a{padding:9px 12px;border-radius:999px;background:rgba(255,255,255,.04);border:1px solid var(--line);text-decoration:none}
|
|
@media (max-width: 1080px){
|
|
.hero,.coverage-layout{grid-template-columns:1fr}
|
|
.topology-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
|
|
}
|
|
@media (max-width: 760px){
|
|
main{padding:14px}
|
|
.hero-grid,.cards,.topology-grid{grid-template-columns:1fr}
|
|
.matrix{grid-template-columns:1fr}
|
|
.arrow{display:none}
|
|
.floor-map{min-height:340px}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="hidden-advanced">
|
|
<div class="incident-tape"></div>
|
|
<main>
|
|
<section class="hero">
|
|
<div style="position:relative;z-index:1">
|
|
<p class="eyebrow">Operator evidence board</p>
|
|
<h1>Home Network Redesign</h1>
|
|
<p class="sub">This is the proposed future-state design for your house and homelab: six purposeful VLANs, a real camera/security lane now instead of later, cleaner SSIDs, stricter policy boundaries, and a staged migration path that avoids lighting the place on fire.</p>
|
|
<div class="nav">
|
|
<a href="#vlan-plan">VLAN plan</a>
|
|
<a href="#ssid-plan">SSID plan</a>
|
|
<a href="#firewall">Firewall</a>
|
|
<a href="#migration">Migration</a>
|
|
<a href="#coverage">Wi-Fi coverage</a>
|
|
</div>
|
|
<div class="hero-grid">
|
|
<div class="hero-stat">
|
|
<strong>6 target VLANs</strong>
|
|
<small>Management, Trusted, Servers, IoT, Guest, Cameras/Security. No more historical junk lanes.</small>
|
|
</div>
|
|
<div class="hero-stat">
|
|
<strong>1 legacy VLAN to kill</strong>
|
|
<small>Old IoT / VLAN 2 goes away after device migration and validation.</small>
|
|
</div>
|
|
<div class="hero-stat">
|
|
<strong>2 AP posture</strong>
|
|
<small>Keep U7 Pro as main AP. Reinstall the U6 LR downstairs if coverage or camera RSSI needs it.</small>
|
|
</div>
|
|
<div class="hero-stat">
|
|
<strong>Camera growth ready now</strong>
|
|
<small>Doorbell, chimes, and future camera gear live on a security lane from day one.</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div style="position:relative;z-index:1" class="panel">
|
|
<h2>Interactive controls</h2>
|
|
<div class="stack" style="margin-top:0">
|
|
<div>
|
|
<div class="muted" style="margin-bottom:8px">Card filter</div>
|
|
<div class="filters">
|
|
<button class="filter active" data-filter="all">All</button>
|
|
<button class="filter" data-filter="network">Network</button>
|
|
<button class="filter" data-filter="wifi">Wi-Fi</button>
|
|
<button class="filter" data-filter="security">Security</button>
|
|
<button class="filter" data-filter="migration">Migration</button>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="muted" style="margin-bottom:8px">Detail level</div>
|
|
<div class="quick-links">
|
|
<button class="toggle" id="detail-toggle">Show advanced details</button>
|
|
<button class="toggle" id="u6-toggle">Enable downstairs U6 LR</button>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="muted" style="margin-bottom:8px">Operator calls</div>
|
|
<div class="hero-actions">
|
|
<span class="pill">Move chimes off Management</span>
|
|
<span class="pill">Retire VLAN 2</span>
|
|
<span class="pill">Split Servers from Trusted</span>
|
|
<span class="pill">Pre-stage Camera VLAN now</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<div class="stack">
|
|
<section class="topology" id="topology">
|
|
<div class="section-head">
|
|
<div>
|
|
<h2 style="margin:0">Current to target topology</h2>
|
|
<p>What exists now versus the lane structure I would put in place before you hand me admin access.</p>
|
|
</div>
|
|
</div>
|
|
<div class="topology-grid">
|
|
<div class="node current" data-tags="network migration">
|
|
<strong>Current Management</strong>
|
|
<small>UDM, switches, APs, plus two Protect chimes that do not belong there.</small>
|
|
<span class="tag">10.5.0.0/24</span>
|
|
</div>
|
|
<div class="arrow">→</div>
|
|
<div class="node target" data-tags="network security">
|
|
<strong>Mgmt VLAN 10</strong>
|
|
<small>Infra only: gateway, switches, APs, management IPs, admin surfaces.</small>
|
|
<span class="tag">10.5.10.0/24</span>
|
|
</div>
|
|
<div class="node current" data-tags="network wifi">
|
|
<strong>Trusted + Servers mixed</strong>
|
|
<small>Main LAN currently holds user clients and service hosts together.</small>
|
|
<span class="tag">10.5.1.0/24</span>
|
|
</div>
|
|
<div class="arrow">→</div>
|
|
<div class="node target" data-tags="network">
|
|
<strong>Trusted VLAN 20</strong>
|
|
<small>Phones, desktops, laptops, Steam Deck, personal endpoints.</small>
|
|
<span class="tag">10.5.20.0/24</span>
|
|
</div>
|
|
<div class="node target" data-tags="network">
|
|
<strong>Servers VLAN 30</strong>
|
|
<small>PD, Serenity, Nomad, Rocinante, and other service hosts.</small>
|
|
<span class="tag">10.5.30.0/24</span>
|
|
</div>
|
|
<div class="node current" data-tags="network migration wifi">
|
|
<strong>Old IoT still real</strong>
|
|
<small>CIA Via on VLAN 2 is still carrying the meaningful smart-home traffic.</small>
|
|
<span class="tag">192.168.1.0/24</span>
|
|
</div>
|
|
<div class="arrow">→</div>
|
|
<div class="node target" data-tags="network migration wifi">
|
|
<strong>IoT VLAN 40</strong>
|
|
<small>All retained smart-home gear lands here after phased migration.</small>
|
|
<span class="tag">10.5.40.0/24</span>
|
|
</div>
|
|
<div class="node current" data-tags="security network">
|
|
<strong>Camera lane underused</strong>
|
|
<small>Doorbell is there, but security gear is not consistently placed yet.</small>
|
|
<span class="tag">10.5.20.0/24 now / repurpose later</span>
|
|
</div>
|
|
<div class="arrow">→</div>
|
|
<div class="node target" data-tags="security network wifi">
|
|
<strong>Camera VLAN 60</strong>
|
|
<small>Doorbell, chimes, future cameras, Protect accessories. Built now, not “someday.”</small>
|
|
<span class="tag">10.5.60.0/24</span>
|
|
</div>
|
|
<div class="node target" data-tags="network wifi">
|
|
<strong>Guest VLAN 50</strong>
|
|
<small>Pure internet-only guest lane with client isolation.</small>
|
|
<span class="tag">10.5.50.0/24</span>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="panel" id="vlan-plan">
|
|
<div class="section-head">
|
|
<div>
|
|
<h2>Target VLAN plan</h2>
|
|
<p>These cards are the final lane definitions I would work from as your network engineer.</p>
|
|
</div>
|
|
</div>
|
|
<div class="cards" id="vlan-cards"></div>
|
|
</section>
|
|
|
|
<section class="panel" id="ssid-plan">
|
|
<div class="section-head">
|
|
<div>
|
|
<h2>SSID plan</h2>
|
|
<p>Fewer SSIDs, clearer meaning, and explicit temporary lanes only where justified.</p>
|
|
</div>
|
|
</div>
|
|
<div class="cards" id="ssid-cards"></div>
|
|
</section>
|
|
|
|
<section class="panel" id="firewall">
|
|
<div class="section-head">
|
|
<div>
|
|
<h2>Firewall intent matrix</h2>
|
|
<p>Not every protocol spelled out yet, but the policy posture is explicit and sane.</p>
|
|
</div>
|
|
</div>
|
|
<div class="matrix" id="fw-matrix"></div>
|
|
<p class="footer-note advanced">Advanced note: discovery helpers like mDNS reflection, Chromecast flows, and specific Home Assistant / MQTT allowances should be explicit exceptions, never implied by a broad allow-any-to-any rule.</p>
|
|
</section>
|
|
|
|
<section class="panel" id="migration">
|
|
<div class="section-head">
|
|
<div>
|
|
<h2>Migration phases</h2>
|
|
<p>Ordered to reduce blast radius: infrastructure first, then servers, then security, then IoT cleanup.</p>
|
|
</div>
|
|
</div>
|
|
<div class="cards" id="phase-cards"></div>
|
|
</section>
|
|
|
|
<section class="panel" id="coverage">
|
|
<div class="section-head">
|
|
<div>
|
|
<h2>Wi-Fi coverage and AP posture</h2>
|
|
<p>The downstairs U6 LR is part of the plan if coverage or camera RSSI says it should be.</p>
|
|
</div>
|
|
</div>
|
|
<div class="coverage-layout">
|
|
<div class="coverage-card">
|
|
<h3>Coverage sketch</h3>
|
|
<div class="floor-map">
|
|
<div class="coverage-zone zone-u7"></div>
|
|
<div class="coverage-zone zone-u6" id="zone-u6"></div>
|
|
<div class="floor upstairs">Upstairs / main coverage zone / existing U7 Pro area</div>
|
|
<div class="floor downstairs">Downstairs / camera + IoT pressure zone / candidate U6 LR restore point</div>
|
|
<div class="ap u7">U7</div>
|
|
<div class="ap u6 off" id="u6-ap">U6</div>
|
|
</div>
|
|
<p class="footer-note">If downstairs coverage is already fine, the U6 can stay cold. If signal loss, roaming pain, or camera RSSI looks weak, install it with wired backhaul and let it carry downstairs 2.4/5 GHz load.</p>
|
|
</div>
|
|
<div class="coverage-card" data-tags="wifi security network">
|
|
<h3>AP guidance</h3>
|
|
<div class="meta">
|
|
<span class="chip ok">Preferred: wired backhaul</span>
|
|
<span class="chip attention">Delay RF micro-tuning</span>
|
|
</div>
|
|
<ul>
|
|
<li>Keep the U7 Pro as the main upstairs AP.</li>
|
|
<li>Reinstall the U6 LR downstairs if validation shows weak coverage or poor roaming.</li>
|
|
<li>Bias cameras toward wired PoE whenever practical; do not solve camera growth with “more Wi-Fi” by default.</li>
|
|
<li>Put both AP management interfaces on Management VLAN 10.</li>
|
|
</ul>
|
|
<details class="advanced">
|
|
<summary>Why not over-tune on day one?</summary>
|
|
<p class="muted">Because the real first win is correct segmentation and sane physical placement. Fancy channel math before the VLAN model is cleaned up is premature wizardry.</p>
|
|
</details>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="panel">
|
|
<div class="section-head">
|
|
<div>
|
|
<h2>Decision summary</h2>
|
|
<p>The crisp operator answer.</p>
|
|
</div>
|
|
</div>
|
|
<div class="cards">
|
|
<div class="legend-card" data-tags="network">
|
|
<h3>Best-fit final shape</h3>
|
|
<ul>
|
|
<li>Management</li>
|
|
<li>Trusted</li>
|
|
<li>Servers</li>
|
|
<li>IoT</li>
|
|
<li>Guest</li>
|
|
<li>Cameras / Security</li>
|
|
</ul>
|
|
</div>
|
|
<div class="legend-card" data-tags="migration">
|
|
<h3>Things to delete</h3>
|
|
<ul>
|
|
<li>Old IoT VLAN 2</li>
|
|
<li>Stale access-port archaeology</li>
|
|
<li>Non-infra devices on Management</li>
|
|
<li>Duplicate SSIDs without a real policy reason</li>
|
|
</ul>
|
|
</div>
|
|
<div class="legend-card" data-tags="security wifi">
|
|
<h3>Security posture</h3>
|
|
<ul>
|
|
<li>IoT and Cameras default-deny toward the rest of the LAN</li>
|
|
<li>Trusted is the operator lane</li>
|
|
<li>Servers expose only explicit services</li>
|
|
<li>Guest is internet-only and isolated</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</main>
|
|
|
|
<script>
|
|
const vlans = [
|
|
{
|
|
name: 'VLAN 10 · Infrastructure / Management',
|
|
subnet: '10.5.10.0/24',
|
|
tags: ['network','security'],
|
|
state: 'ok',
|
|
chips: ['Infra only','No client junk'],
|
|
summary: 'Gateway, switches, APs, management interfaces, and admin surfaces. This lane becomes sacred.',
|
|
bullets: [
|
|
'Move Protect chimes out of Management.',
|
|
'Only designated admin clients and tools may initiate into this VLAN.',
|
|
'Use this as the native management lane for network gear and APs.'
|
|
],
|
|
advanced: 'This is where I would park UDM, USW Pro HD 24, USW-24-PoE, U7 Pro, U6 LR, and any OOB or appliance management IPs.'
|
|
},
|
|
{
|
|
name: 'VLAN 20 · Trusted Clients',
|
|
subnet: '10.5.20.0/24',
|
|
tags: ['network','wifi'],
|
|
state: 'ok',
|
|
chips: ['Phones + personal devices','Main user lane'],
|
|
summary: 'Your daily-driver devices live here: phones, laptops, desktops, tablets, Steam Deck, handhelds.',
|
|
bullets: [
|
|
'Primary trusted SSID maps here.',
|
|
'Trusted clients can administer servers and selected management surfaces.',
|
|
'Do not use this lane for “smart” junk just because it is convenient.'
|
|
],
|
|
advanced: 'Whiskey Neat Fuck Ice can temporarily remain as a compat/isolation flavor on the same VLAN if you still need it during cleanup.'
|
|
},
|
|
{
|
|
name: 'VLAN 30 · Servers / Core Services',
|
|
subnet: '10.5.30.0/24',
|
|
tags: ['network'],
|
|
state: 'attention',
|
|
chips: ['Service hosts','Cleaner east-west policy'],
|
|
summary: 'Separate always-on service hosts from your person-devices so the firewall can speak clearly.',
|
|
bullets: [
|
|
'PD, Serenity, Nomad, Rocinante belong here.',
|
|
'Trusted can reach this lane broadly for admin and use.',
|
|
'IoT and Cameras get only tightly scoped access into published services.'
|
|
],
|
|
advanced: 'If FlyingDutchman is a real service host, it lands here too. Otherwise keep it on Trusted.'
|
|
},
|
|
{
|
|
name: 'VLAN 40 · IoT / Smart Home',
|
|
subnet: '10.5.40.0/24',
|
|
tags: ['network','wifi','migration'],
|
|
state: 'attention',
|
|
chips: ['Replace Old IoT','Default deny'],
|
|
summary: 'This is the real home for thermostats, appliances, MyQ, Google Home-class devices, and retained smart-home junk.',
|
|
bullets: [
|
|
'Repoint CIA Via here during migration or create a temporary migration SSID.',
|
|
'Allow DNS, NTP, internet, and only explicit local service exceptions.',
|
|
'Treat Google/casting discovery as an exception set, not as a reason to flatten the network.'
|
|
],
|
|
advanced: 'This replaces Old IoT VLAN 2 entirely once migration is complete.'
|
|
},
|
|
{
|
|
name: 'VLAN 50 · Guest',
|
|
subnet: '10.5.50.0/24',
|
|
tags: ['network','wifi'],
|
|
state: 'ok',
|
|
chips: ['Internet only','Client isolation'],
|
|
summary: 'Visitors and untrusted BYOD devices live here and get exactly zero reason to see the rest of the house.',
|
|
bullets: [
|
|
'Dedicated guest SSID only.',
|
|
'Enable client isolation.',
|
|
'No RFC1918 access back into the lab or house networks.'
|
|
],
|
|
advanced: 'Keep this boring. That is the point.'
|
|
},
|
|
{
|
|
name: 'VLAN 60 · Cameras / Security',
|
|
subnet: '10.5.60.0/24',
|
|
tags: ['network','security','wifi'],
|
|
state: 'ok',
|
|
chips: ['Build now','Ready for camera growth'],
|
|
summary: 'Doorbell, Protect chimes, future cameras, and security accessories get their own lane now so you do not have to revisit the design later.',
|
|
bullets: [
|
|
'Move front-doorbell and both chimes here.',
|
|
'Prefer wired PoE cameras on this VLAN as the fleet grows.',
|
|
'Allow only Protect/NVR-related traffic, DNS, NTP, updates, and admin access from Trusted.'
|
|
],
|
|
advanced: 'If you add a real NVR or Protect host later, it can stay on Servers VLAN while publishing only the needed interfaces to Cameras/Security.'
|
|
}
|
|
];
|
|
|
|
const ssids = [
|
|
{
|
|
name: 'Trusted SSID',
|
|
tags: ['wifi'],
|
|
chips: ['Maps to VLAN 20','Main client Wi-Fi'],
|
|
summary: 'Use one primary trusted SSID for normal day-to-day devices.',
|
|
bullets: ['Yer a Wifi Harry is the natural candidate to remain the main trusted SSID.', 'Keep 6 GHz here if the client mix supports it.']
|
|
},
|
|
{
|
|
name: 'Trusted-Compat (temporary)',
|
|
tags: ['wifi','migration'],
|
|
chips: ['Optional','Retire later if possible'],
|
|
summary: 'Only keep a second trusted-flavored SSID if it solves a real compatibility or isolation problem.',
|
|
bullets: ['Whiskey Neat Fuck Ice can serve as a temporary compat/isolation lane.', 'If it is no longer solving a problem, kill it.']
|
|
},
|
|
{
|
|
name: 'IoT SSID',
|
|
tags: ['wifi','migration'],
|
|
chips: ['Maps to VLAN 40','2.4 GHz friendly'],
|
|
summary: 'This becomes the home for all retained smart-home Wi-Fi devices.',
|
|
bullets: ['CIA Via can be repointed here during migration to reduce user retraining.', 'Keep broad compatibility; this is not where we get fancy.']
|
|
},
|
|
{
|
|
name: 'Security SSID',
|
|
tags: ['wifi','security'],
|
|
chips: ['Maps to VLAN 60','For doorbells/chimes/cameras'],
|
|
summary: 'A dedicated security Wi-Fi lane lets you separate Protect/security traffic from the general IoT pile.',
|
|
bullets: ['UNEF\'s Playhouse is the obvious candidate to keep for this purpose.', 'Use it for the doorbell, chimes, and any Wi-Fi cameras/security accessories.']
|
|
},
|
|
{
|
|
name: 'Guest SSID',
|
|
tags: ['wifi'],
|
|
chips: ['Maps to VLAN 50','Client isolation'],
|
|
summary: 'One guest lane. Internet only. No drama.',
|
|
bullets: ['Keep it separate from your real networks.', 'No internal access exceptions unless there is a compelling reason.']
|
|
}
|
|
];
|
|
|
|
const phases = [
|
|
{
|
|
name: 'Phase 0 · Staging and rollback points',
|
|
tags: ['migration','network'],
|
|
chips: ['No cutover yet'],
|
|
summary: 'Create target VLANs, port profiles, and draft firewall rules before moving anything.',
|
|
bullets: ['Build trunk-uplink, access-management, access-trusted, access-servers, access-iot, access-guest, access-cameras profiles.', 'Document rollback path before each cutover.']
|
|
},
|
|
{
|
|
name: 'Phase 1 · Infrastructure hygiene',
|
|
tags: ['migration','network','security'],
|
|
chips: ['Protect mgmt purity'],
|
|
summary: 'Move all network gear and only network gear into the Management lane.',
|
|
bullets: ['UDM, switches, APs, management surfaces.', 'Get the Protect chimes out of Management.']
|
|
},
|
|
{
|
|
name: 'Phase 2 · Servers split from Trusted',
|
|
tags: ['migration','network'],
|
|
chips: ['Service boundary'],
|
|
summary: 'Move core service hosts into Servers VLAN 30 and validate name resolution and reachability.',
|
|
bullets: ['PD, Serenity, Nomad, Rocinante first.', 'Update static addressing, DNS, ACLs, and any service bindings.']
|
|
},
|
|
{
|
|
name: 'Phase 3 · Security lane now',
|
|
tags: ['migration','security','wifi'],
|
|
chips: ['Camera growth ready'],
|
|
summary: 'Move the doorbell and chimes into Cameras/Security before you expand the camera fleet.',
|
|
bullets: ['This builds the right landing zone now.', 'Future camera rollout becomes additive rather than redesign work.']
|
|
},
|
|
{
|
|
name: 'Phase 4 · Retire Old IoT',
|
|
tags: ['migration','wifi'],
|
|
chips: ['Most user-visible phase'],
|
|
summary: 'Batch-migrate retained smart-home devices off CIA Via / VLAN 2 and onto the new IoT lane.',
|
|
bullets: ['Easy cloud devices first.', 'Thermostats next.', 'Google/casting devices last because they are the most likely to be annoying.']
|
|
},
|
|
{
|
|
name: 'Phase 5 · Clean SSIDs and stale rules',
|
|
tags: ['migration','wifi','network'],
|
|
chips: ['Final cleanup'],
|
|
summary: 'Disable the old SSID, delete VLAN 2, and remove historical special cases.',
|
|
bullets: ['Retire temporary compat SSIDs if not needed.', 'Delete stale firewall rules and stale port assignments.']
|
|
}
|
|
];
|
|
|
|
const fwRows = [
|
|
['Source / Target','Management','Servers','IoT','Cameras'],
|
|
['Trusted','Admin only','Allow','Selective allow','Allow for operators'],
|
|
['Servers','Rare and explicit','Internal service mesh only','Explicit services only','Protect / NVR flows only'],
|
|
['IoT','Deny','Explicit exceptions only','Same VLAN only','Deny'],
|
|
['Cameras','Deny','Protect / NVR only','Deny','Same VLAN only']
|
|
];
|
|
|
|
const stateClass = { ok:'ok', attention:'attention', warn:'warn' };
|
|
|
|
function cardTemplate(item, kind='vlan-card') {
|
|
return `
|
|
<article class="${kind}" data-tags="${item.tags.join(' ')}">
|
|
<h3>${item.name}</h3>
|
|
${item.subnet ? `<div class="meta"><span class="chip ${stateClass[item.state] || ''}">${item.subnet}</span>${item.chips.map(c=>`<span class="chip">${c}</span>`).join('')}</div>` : `<div class="meta">${item.chips.map(c=>`<span class="chip">${c}</span>`).join('')}</div>`}
|
|
<p class="muted">${item.summary}</p>
|
|
<ul>${item.bullets.map(b=>`<li>${b}</li>`).join('')}</ul>
|
|
${item.advanced ? `<details class="advanced"><summary>Advanced detail</summary><p class="muted">${item.advanced}</p></details>` : ''}
|
|
</article>`;
|
|
}
|
|
|
|
document.getElementById('vlan-cards').innerHTML = vlans.map(v => cardTemplate(v)).join('');
|
|
document.getElementById('ssid-cards').innerHTML = ssids.map(v => cardTemplate(v,'ssid-card')).join('');
|
|
document.getElementById('phase-cards').innerHTML = phases.map(v => cardTemplate(v,'phase-card')).join('');
|
|
document.getElementById('fw-matrix').innerHTML = fwRows.flatMap((row, rIdx) => row.map((cell, cIdx) => `<div class="cell ${(rIdx===0||cIdx===0)?'head':''}">${cell}</div>`)).join('');
|
|
|
|
const filters = document.querySelectorAll('.filter');
|
|
const filterable = document.querySelectorAll('[data-tags]');
|
|
filters.forEach(btn => btn.addEventListener('click', () => {
|
|
filters.forEach(b => b.classList.remove('active'));
|
|
btn.classList.add('active');
|
|
const tag = btn.dataset.filter;
|
|
filterable.forEach(el => {
|
|
if (tag === 'all') el.classList.remove('filter-hide');
|
|
else el.classList.toggle('filter-hide', !(el.dataset.tags || '').split(' ').includes(tag));
|
|
});
|
|
localStorage.setItem('network-plan-filter', tag);
|
|
}));
|
|
|
|
const detailToggle = document.getElementById('detail-toggle');
|
|
detailToggle.addEventListener('click', () => {
|
|
document.body.classList.toggle('hidden-advanced');
|
|
const advancedVisible = !document.body.classList.contains('hidden-advanced');
|
|
detailToggle.textContent = advancedVisible ? 'Hide advanced details' : 'Show advanced details';
|
|
detailToggle.classList.toggle('active', advancedVisible);
|
|
localStorage.setItem('network-plan-advanced', advancedVisible ? '1' : '0');
|
|
});
|
|
|
|
const u6Toggle = document.getElementById('u6-toggle');
|
|
const u6Ap = document.getElementById('u6-ap');
|
|
const u6Zone = document.getElementById('zone-u6');
|
|
function setU6(on){
|
|
u6Ap.classList.toggle('off', !on);
|
|
u6Zone.style.display = on ? 'block' : 'none';
|
|
u6Toggle.textContent = on ? 'Disable downstairs U6 LR' : 'Enable downstairs U6 LR';
|
|
u6Toggle.classList.toggle('active', on);
|
|
localStorage.setItem('network-plan-u6', on ? '1' : '0');
|
|
}
|
|
u6Toggle.addEventListener('click', () => setU6(u6Ap.classList.contains('off')));
|
|
|
|
const savedFilter = localStorage.getItem('network-plan-filter');
|
|
if (savedFilter) {
|
|
const btn = [...filters].find(b => b.dataset.filter === savedFilter);
|
|
if (btn) btn.click();
|
|
}
|
|
if (localStorage.getItem('network-plan-advanced') === '1') detailToggle.click();
|
|
setU6(localStorage.getItem('network-plan-u6') === '1');
|
|
</script>
|
|
</body>
|
|
</html>
|