14 KiB
Cascades — Voice VLAN (VLAN 30) Cutover Runbook + Recon
- Created: 2026-06-16 (Howard-Home / claude-main)
- Status: APPROVED TO EXECUTE — Richard confirmed 2026-06-17. pfSense PART A BUILT + VERIFIED 2026-06-17 (VLAN 30 iface
igc1.30/opt241 @10.0.30.1/24; DHCP10.0.30.100-.250, DNS8.8.8.8/1.1.1.1; 4 isolation rules enforced, verified viapfctl -srto match the Guest VLAN exactly — any-proto quick blocks to 192.168.0.0/22 + 10.0.0.0/8 + 172.16.0.0/12, then pass any). Remaining: Part B (UniFi VOICE network + voice PPSK), then the live device moves in a maintenance window. - PART B BUILT 2026-06-17 (build-only): UniFi VOICE network created (VLAN Only, VLAN 30, Cascades site). Voice PPSK key DEFINED on the CSCNet SSID -> VOICE network (configured in UniFi only; NOT yet entered on any handset, so no device is on VLAN 30 — pure build). Key vaulted at
clients/cascades-tucson/wifi-voice-ppsk.sops.yaml(do NOT paste it here). Remaining = the live device moves (USW-16-PoE ports 1-8 + 16 -> VOICE; re-point 22 Poly phones to the voice key) in a maintenance window with Richard. - Gotcha caught 2026-06-17: first GUI build set the rule Protocol to TCP — that leaves UDP (SIP/RTP/DNS) un-blocked to internal (leaks via the floating
pass inet all). Isolation rules MUST be Protocol=Any. Fixed via the pfSense PHP config API.
Vendor confirmation (Richard Turner, 2026-06-17) — materially simplifies the plan
Richard replied "we are good to start." Two confirmations change the runbook:
- Remote desktop gets its IP from DHCP (not static, as recon had assumed). Verified on pfSense 2026-06-17: no static mapping for
e4:e7:49:52:3a:06in ISCdhcpd.conf, but an active lease exists (client-hostname "Vertical-Remote"). => Desktop cutover is zero-touch: flip port 16 -> VOICE and it re-DHCPs onto10.0.30.x. No NIC change, no Vertical coordination needed for the desktop itself. - Vertical reaches the desktop via LogMeIn, NOT the pfSense OpenVPN. => Part A step 6 (OpenVPN Client-Specific-Override + his cert CN) is DROPPED. LogMeIn is an outbound agent, so the desktop only needs internet egress on VOICE — already granted by firewall rule (d). This is also better for HIPAA: a LogMeIn session lands on the isolated voice VLAN with no path to PHI / main LAN / VLAN 20.
Also resolved: DHCP backend = ISC dhcpd (Kea config present but dormant), confirmed live 2026-06-17 — reservations placed out-of-pool (below .100) are safe.
- Driver: Vertical (VoIP vendor, Richard Turner RTurner@vertical.com) cannot reach the phones from the remote-management desktop, and phone IPs drift. Root cause: when the network was segmented into VLANs, the Vertical remote desktop and the wired phones were left on the original LAN while the wireless phones landed on VLAN 20 — so the desktop has no path to the wireless phones (main-LAN -> VLAN 20 is blocked at pfSense).
Goal
Consolidate ALL voice gear (Poly WiFi phones + AudioCodes wired phones + Vertical-Remote desktop) onto a dedicated, isolated voice network. Voice reaches the internet; blocked from main LAN / VLAN 20 / PHI. Vertical's pfSense OpenVPN scoped to the voice subnet only.
VOICE network: VLAN 30
Subnet/gateway: 10.0.30.0/24 gw 10.0.30.1 (pfSense igc1.30)
DHCP pool: 10.0.30.100 - 10.0.30.250
Reservations: NONE (2026-06-17 — Howard: desktop needs no static IP to connect; it's
a normal DHCP client like the phones; LogMeIn is name/agent-based)
Desktop: dynamic lease from the pool (Vertical-Remote, e4:e7:49:52:3a:06)
Systems
pfSense 192.168.0.1 does ALL routing + DHCP. UniFi (UOS controller 172.16.3.29, Cascades site 685f39068e65331c46ef6dd2) is L2 only here — every UniFi network is purpose: vlan-only (no subnets in UniFi). So building VLAN 30 touches BOTH systems.
Confirmed architecture (UOS controller, 2026-06-16)
| Device class | Count | Attach | Currently lands on |
|---|---|---|---|
| Poly phones | 22 active (~29 historical) | WiFi, SSID CSCNet, APs building-wide | VLAN 20 "Internal" (10.0.20.x) |
| AudioCodes phones | 8 | Wired, USW-16-PoE ports 1-8 | "Default" / main LAN (192.168.2/3.x) |
| Vertical-Remote desktop | 1 | Wired, USW-16-PoE port 16 | "Default" / main LAN (192.168.2.180, static) |
CSCNet is a shared PPSK SSID (wlanconf 685f39078e65331c46ef7ee5, private_preshared_keys_enabled:true, base networkconf = Default, vlan_enabled:false). ~230 per-key->network mappings: most keys map to per-room resident VLANs (101-631), a few to Default, and one phone key maps to "Internal"/VLAN 20 (networkconf 69405ba36db796548c947130). Historical CSCNet clients: 1,190 (residents' IoT/TVs/phones/laptops + staff + the phones). => Do NOT repoint the CSCNet SSID itself — that would move every resident/staff device. Move the phones at the PPSK level instead.
Networks of interest:
- Default (main LAN):
685f39078e65331c46ef8ac4,192.168.0.0/22 - Internal (VLAN 20):
69405ba36db796548c947130,10.0.20.0/24 - Guest (VLAN 50):
10.0.50.0/24 - OpenVPN Server:
192.168.8.1/24(purpose remote-user-vpn) — Vertical comes in here.
PBX recon (CS-SERVER via GuruRMM, 2026-06-16)
Probed from CS-SERVER (192.168.2.254, same LAN segment) — read-only.
| Target | TCP open | SIP UDP 5060 | Conclusion |
|---|---|---|---|
192.168.2.180 (desktop) |
3389 (RDP) only | no reply | Not a PBX — RDP management/jump box |
192.168.2.228 (CS-QB, labeled "VoIP server") |
445 (SMB) only | no reply | Not a live SIP PBX — behaves like an SMB box despite the label |
Implication: no on-prem SIP PBX detected -> phones almost certainly register to a cloud/hosted PBX (Vertical). If confirmed, the voice VLAN only needs internet egress and the on-prem PBX pinhole (Part A step 5b) is NOT needed. Caveat: external port view only — a non-standard port / known-peer-only / host-firewalled PBX can't be 100% excluded, so Richard's confirm is the authority.
PART A — pfSense (https://192.168.0.1)
- VLAN interface: Interfaces -> VLANs -> Add: Parent
igc1, Tag30, DescVOICE. - Assign + IP: Interfaces -> Assignments -> add
igc1.30-> Enable, Static10.0.30.1/24. - DHCP: Services -> DHCP Server -> VOICE: enable, range
10.0.30.100-.250, DNS8.8.8.8, 1.1.1.1(PUBLIC resolvers — must NOT be10.0.30.1; the isolation rules below block the firewall IP, and this matches how the Guest VLAN already resolves DNS). - Reservation: SKIP (2026-06-17). Desktop needs no static IP to connect (LogMeIn is name/agent-based) — it takes a normal pool lease like the phones, and reaches all phones on-subnet regardless. No static mappings needed for anything.
- Firewall (VOICE tab) — CLONE THE GUEST VLAN (VLAN 50 / igc1.50), verified 2026-06-17 as the only properly-isolated template. Four interface rules, top-to-bottom (GUI interface rules are
quick-> first match wins, so blocks bite before the internet pass). No RFC1918 alias — use literal CIDRs, matching the Guest convention:- (1) BLOCK: VOICE subnets ->
192.168.0.0/22(Block VOICE to LAN) - (2) BLOCK: VOICE subnets ->
10.0.0.0/8(Block VOICE to private 10.x — includes own subnet, but intra-subnet is L2-switched so desktop<->phones still work) - (3) BLOCK: VOICE subnets ->
172.16.0.0/12(Block VOICE to ACG mgmt) - (4) PASS: VOICE subnets ->
any(internet egress — cloud PBX + LogMeIn + public DNS) - No DNS/NTP-to-firewall rule (would be blocked by rule 2 and isn't needed — DNS is public via DHCP). No on-prem PBX pinhole (cloud PBX). DO NOT add VOICE to the
All_Networksinterface group (Guest isn't in it; isolation depends on staying out). - Corrects the earlier draft (DNS-to-firewall + RFC1918 alias) and the earlier wrong idea of cloning VLAN 20 — VLAN 20 is NOT isolated (only rule = opt238net->lan; everything else rides a floating
pass inet all).
- (1) BLOCK: VOICE subnets ->
OpenVPN — reach desktop on VOICE, scoped to voice only— NOT NEEDED (2026-06-17). Vertical uses LogMeIn (outbound agent), not the pfSense OpenVPN, to reach the desktop. The desktop's internet egress on VOICE (rule (d)) is all LogMeIn requires. No CSO, no cert CN, no OpenVPN firewall rules for Vertical. (Howard's own OpenVPN access is unaffected.)
PART B — UniFi (UOS controller)
- Network: Settings -> Networks -> Add:
VOICE, purposeVLAN Only, VLAN30. - Wired ports (USW-16-PoE): set Native Network = VOICE (untagged) on ports 1-8 (AudioCodes) and port 16 (desktop). Then bounce each moved port (PoE Power-Cycle for the AudioCodes; disable/enable for the desktop) — see the CRITICAL note in the Cutover sequence. No NIC change needed (desktop is DHCP).
- Wireless Poly (PPSK): Settings -> Profiles -> Private Pre-Shared Keys (CSCNet) -> add a new key -> Network VOICE (vault the key). Re-point each Poly phone's WiFi to the voice key (by hand / Vertical provisioning). Also fixes the 2 currently mis-keyed phones (one on VLAN 422, one on Default). [Alt zero-touch: remap the existing phone key VLAN 20 -> VOICE, ONLY if that key is confirmed phone-exclusive — ~70 non-phone devices also showed on VLAN 20, so default to the dedicated key.]
- Confirm inter-switch / AP uplinks + the pfSense trunk carry VLAN 30 (default "All" port profile auto-includes it).
Cutover sequence (avoid stranding anything)
CRITICAL — re-VLANing a wired port does NOT force a new IP. Changing a switch port's native VLAN leaves the device's NIC link UP, so the OS keeps its OLD DHCP lease and never sends a fresh DISCOVER on the new VLAN (its unicast renewal to the old DHCP server is then blocked by the VOICE isolation rules, so it just holds the stale IP until lease expiry). A UniFi client block/unblock does NOT fix this — that's a MAC filter, not a link bounce. After every wired port move you MUST bounce the link to force re-DHCP (proven on the Vertical desktop 2026-06-17: stuck on
192.168.2.180until port 16 was bounced -> pulled10.0.30.201). Methods:
- AudioCodes (PoE-powered): UniFi -> the switch -> port -> Power Cycle (cycles PoE, reboots the phone, forces fresh DHCP). Cleanest for ports 1-8.
- Non-PoE device (the desktop): toggle the port admin state (disable -> re-enable), or on the device
ipconfig /release && /renew, or reboot it. (Scripted bounce = PUTrest/device/<id>port_overrideswith port'sforward:disabled, then restore — needs theX-CSRF-Tokenfrom login headerx-updated-csrf-token.)
- Build everything with no live impact: pfSense VLAN/DHCP/firewall, UniFi network, create the voice PPSK. [DONE 2026-06-17]
- AudioCodes: flip USW-16-PoE ports 1-8 -> VOICE, then Power Cycle each of ports 1-8 so the phones re-DHCP onto
10.0.30.x+ re-register (brief blip). - Poly: re-key to voice PPSK -> they re-associate (a WiFi re-auth IS a fresh DHCP, no separate bounce needed) and roam onto VOICE.
- Desktop (DHCP, LogMeIn): flip port 16 -> VOICE, then bounce port 16 (disable/re-enable) so it re-DHCPs to a
10.0.30.xlease. LogMeIn re-homes over internet egress automatically (no NIC change, no static IP, no Vertical action needed). Brief blip only. - Verify each move on pfSense (
/var/dhcpd/var/db/dhcpd.leases+arp -an | grep igc1.30) — a device still on its old IP means the bounce didn't take; bounce again. - Confirm with Richard: LogMeIn reconnects to the desktop, and from the desktop he can reach the phones on
10.0.30.x.
Validation
- VOICE DHCP leases show phones AND the desktop on
10.0.30.x(all dynamic). - From desktop: reach several phones (Poly + AudioCodes).
- Isolation negative test: from VOICE, CANNOT reach CS-SERVER
192.168.2.254or10.0.20.x. - Phones registered / dial tone on a sample handset.
- Richard: LogMeIn -> desktop -> reach a phone's web UI on
10.0.30.x.
Rollback
Revert the UniFi port native VLAN (1-8, 16) + the PPSK key to their prior networks, then bounce the ports so devices re-DHCP back onto the old segments. pfSense VOICE iface/DHCP/rules can stay inert or be removed. Desktop is DHCP (no NIC revert needed) — it just re-leases on the old VLAN after the bounce.
Open items
- [RESOLVED 2026-06-17] Desktop is DHCP (verified on pfSense) -> zero-touch cutover.
- [RESOLVED 2026-06-17] Remote access is LogMeIn, not OpenVPN -> step 6 dropped; only internet egress needed.
- [RESOLVED 2026-06-17] DHCP backend = ISC dhcpd (Kea dormant) -> out-of-pool reservations safe.
- [OPEN] Confirm phones register to cloud/hosted PBX (recon says yes) -> if so, Part A step 5b pinhole stays skipped. Low risk: if a phone fails to register after cutover, add the pinhole.
- [OPEN] Schedule the maintenance window for the live port flips (AudioCodes ports 1-8 = brief blip; port 16 desktop = brief blip).
- [OPEN] Poly re-key method: 22 WiFi phones must be pointed at the new voice PPSK — by hand per phone, or via Vertical provisioning. Richard offered to help during the transition; bulk provisioning by Vertical is the clean path.
Appendix — device inventory (MACs)
AudioCodes (wired, USW-16-PoE):
port1 00:90:8f:da:98:05 port5 00:90:8f:e1:3d:90
port2 00:90:8f:e2:40:5e port6 00:90:8f:e1:3d:5e
port3 00:90:8f:e2:d2:a4 port7 00:90:8f:e1:3d:a9
port4 00:90:8f:e1:3d:de port8 00:90:8f:e1:3e:17
Poly (wireless, CSCNet -> voice PPSK):
48:25:67:d0:af:10 48:25:67:64:8a:88 48:25:67:64:95:6b
48:25:67:d0:b4:26 48:25:67:64:93:34 48:25:67:64:8e:ae
48:25:67:64:81:8e 48:25:67:64:93:25 48:25:67:64:92:6b
48:25:67:d0:ae:3e 48:25:67:64:95:62 48:25:67:64:93:d3
48:25:67:d0:b8:ac 48:25:67:64:94:84 48:25:67:64:94:ba
48:25:67:64:8f:14 48:25:67:64:95:74 48:25:67:64:8f:0b
48:25:67:d0:b1:83 48:25:67:64:92:89 48:25:67:64:8f:1d
48:25:67:a3:f8:3b
(22 total — source: Richard's 2026-06-16 scan list)
Desktop: e4:e7:49:52:3a:06 (Vertical-Remote) -> reserve 10.0.30.10.