# 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 (go for VLAN build + device moves). Maintenance window still to be set for the live port flips.

## Vendor confirmation (Richard Turner, 2026-06-17) — materially simplifies the plan
Richard replied "we are good to start." Two confirmations change the runbook:
1. **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:06` in ISC `dhcpd.conf`, but an active lease exists (`client-hostname "Vertical-Remote"`). => **Desktop cutover is zero-touch**: flip port 16 -> VOICE and it re-DHCPs onto `10.0.30.x`. No NIC change, no Vertical coordination needed for the desktop itself.
2. **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:    below .100 (out of pool -> safe on both ISC and Kea)
Desktop:         10.0.30.10  (Vertical-Remote, e4:e7:49:52:3a:06) -> set NIC to DHCP
```

## 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`)

1. **VLAN interface:** Interfaces -> VLANs -> Add: Parent `igc1`, Tag `30`, Desc `VOICE`.
2. **Assign + IP:** Interfaces -> Assignments -> add `igc1.30` -> Enable, Static `10.0.30.1/24`.
3. **DHCP:** Services -> DHCP Server -> VOICE: enable, range `10.0.30.100-.250`, DNS `10.0.30.1`.
4. **Reservation (desktop):** Static Mappings -> `e4:e7:49:52:3a:06` = `10.0.30.10`, hostname `Vertical-Remote`. (Phones optional — see Appendix; they stay reachable from the desktop on-subnet regardless.)
5. **Firewall (VOICE tab), top-to-bottom:**
   - Alias `RFC1918` = `10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16`.
   - (a) PASS: VOICE net -> This Firewall (10.0.30.1) ports 53, 123.
   - (b) **CONDITIONAL** PASS: VOICE net -> `<on-prem PBX IP>` SIP/RTP/provisioning. **Recon says SKIP (cloud PBX); add only if Richard confirms an on-prem PBX.**
   - (c) BLOCK: VOICE net -> `RFC1918`. (isolation)
   - (d) PASS: VOICE net -> any. (internet)
6. ~~**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)

7. **Network:** Settings -> Networks -> Add: `VOICE`, purpose `VLAN Only`, VLAN `30`.
8. **Wired ports (USW-16-PoE):** set Native Network = VOICE (untagged) on **ports 1-8** (AudioCodes) and **port 16** (desktop). AudioCodes re-DHCP automatically; desktop needs Vertical's NIC change.
9. **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)
1. Build everything with no live impact: pfSense VLAN/DHCP/firewall, OpenVPN CSO+rules, UniFi network, create the voice PPSK.
2. **AudioCodes:** flip USW-16-PoE ports 1-8 -> VOICE. Re-DHCP + re-register (brief blip).
3. **Poly:** re-key to voice PPSK. Roam onto VOICE.
4. **Desktop (zero-touch — DHCP, LogMeIn):** flip port 16 -> VOICE. Desktop re-DHCPs to `10.0.30.10` (its reservation). LogMeIn re-homes over internet egress automatically (no NIC change, no Vertical action needed). Brief blip only.
5. 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 on `10.0.30.x`; desktop on `10.0.30.10`.
- From desktop: reach several phones (Poly + AudioCodes).
- Isolation negative test: from VOICE, CANNOT reach CS-SERVER `192.168.2.254` or `10.0.20.x`.
- Phones registered / dial tone on a sample handset.
- Richard: VPN -> `10.0.30.10` -> phone web UI.

## Rollback
Revert UniFi port native VLAN (1-8, 16) + the PPSK key to prior networks; AudioCodes/desktop re-DHCP onto old segments. pfSense VOICE iface/DHCP/rules + OpenVPN CSO can stay inert or be removed. Desktop: Vertical reverts NIC to static `192.168.2.180` if needed.

---

## 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`.
