Claude b43eed0546 Use show poe-main-status instead of per-port PoE command
show poe-port status rejects all argument formats on this firmware;
show poe-main-status gives overall PoE power and health data instead.

https://claude.ai/code/session_01JR2EMK7rwrZJowpstcaxQ6
2026-03-24 03:35:56 +00:00
2026-03-23 08:52:01 -04:00
2026-03-23 08:52:01 -04:00
2026-03-23 08:52:01 -04:00
2026-03-23 08:52:01 -04:00
2026-03-23 08:52:01 -04:00
2026-03-23 08:52:01 -04:00

Avaya / Extreme ERS Switch Manager

A browser-based management interface for Avaya / Extreme Networks ERS switches. You click buttons. The software figures out the CLI. You never type a switch command.

Compatible with: ERS 5928, ERS 5948, ERS 5952, ERS 5952-PWR+, ERS 59100GTS-PWR+


Physical Setup — First Time Out of the Box

Everything here happens before you run any software. You need a console cable and a laptop.


Step 1 — Find the Service Port

The console (service) port is a physical RJ-45 serial port on the switch. It is not a regular ethernet port.

ERS 59100GTS-PWR+: The console port is on the front panel, left side. It is labelled "Console" and looks like a standard ethernet jack but is wired as RS-232 serial. It is located next to the USB port and the out-of-band management port.

ERS 5952 / 5952-PWR+: The console port is on the front panel, far left, labelled "Console".


Step 2 — Get a Console Cable

Search "RJ45 to USB console cable Cisco compatible" — around $8. This is the same cable used for Cisco, Juniper, and most enterprise switches. It has an RJ-45 plug on one end and USB-A on the other.

Do not use a standard ethernet cable — it will not work.


Step 3 — Connect and Open a Terminal

Plug the RJ-45 end into the switch console port. Plug USB into your laptop.

Settings: 9600 baud · 8 data bits · No parity · 1 stop bit · No flow control

Open a terminal session:

OS Command
Linux sudo picocom -b 9600 /dev/ttyUSB0
Mac screen /dev/tty.usbserial-* 9600
Windows PuTTY → Serial → COM port → 9600 baud

To find your COM/device name if unsure:

  • Linux: ls /dev/ttyUSB* before and after plugging in
  • Mac: ls /dev/tty.usb* before and after plugging in
  • Windows: Device Manager → Ports (COM & LPT)

Step 4 — Power On and Read the Boot Screen

Power on the switch. You will see a banner like this:

Enter Ctrl-Y to begin.

*************************************************************
*** Ethernet Routing Switch 59100GTS-PWR+                ***
*** Copyright (C) 1996-2024 Extreme Networks.            ***
*** HW:22    FW:7.5.0.4    SW:v7.9.6.015                ***
*************************************************************

Press Ctrl-Y. The switch is waiting for this keypress to continue booting — it will not proceed without it. After pressing Ctrl-Y the switch runs POST and boots normally in about 6090 seconds.

When it is ready you will see:

Login:

Step 5 — Log In with Default Credentials

Login:    admin
Password: (press Enter — no password by default)

If that fails, try admin / admin. If the switch was previously configured you may need to do a factory reset (see Troubleshooting below).

You will land at the 5952# or 59100GTS-PWR+# prompt in privileged exec mode.


Step 6 — Bootstrap VLAN 99 via Console

This is the only time you need the console cable for normal operation. Enter these commands one at a time, waiting for the prompt before each:

enable
configure terminal
vlan create 99 name "Management" type port
interface vlan 99
ip address 192.168.99.1 255.255.255.0
no shutdown
exit
vlan members add 99 1
vlan pvid 1 99
ip ssh
username admin password YourPassword
end
copy running-config nvram:config.cfg

Replace 1 with the port number your management computer will plug into. Replace YourPassword with a strong password (832 characters; allowed special characters: ! @ # $ % ^ & * - _ = + [ ] ; : , . / — no spaces, no quotes).

ERS 59100 note: Port numbering on the 59100 is 1/1 through 1/96 for copper and 1/97 through 1/100 for SFP+ uplinks. Substitute accordingly:

vlan members add 99 1/1
vlan pvid 1/1 99

After the last command the switch confirms with CP1 [07/04/15 12:00:00.000:INFO]: Operation Success or similar.


Step 7 — Give the Management Computer a Static IP

On the machine that will run the switch manager software:

# Find your interface name first
ip link show

# Set a static IP on the management network interface (adjust eth0 to your interface)
sudo ip addr add 192.168.99.50/24 dev eth0
sudo ip link set eth0 up

Verify: ping 192.168.99.1 — you should get replies from the switch.


Step 8 — Run the Setup Script

python Avaya_5952_setup.py

The script handles everything from here. When it pauses and asks you to load the SSH public key onto the switch, it will show you exactly what to paste into the console.


Installation

Copy Avaya_5952_setup.py to your always-on management computer (Raspberry Pi, HP T620 thin client, old computer or laptop) and run:

python Avaya_5952_setup.py

That is the entire installation process. The script handles everything automatically. The only step requiring human intervention is loading the SSH public key onto the switch via console cable — the script pauses, shows you exactly what to type, and waits for you to confirm before continuing.


What the Setup Script Does

The script runs 21 steps automatically:

  1. Writes all project files (backend, frontend source, this README)
  2. Installs system packages (picocom, qrencode, wireguard-tools)
  3. Adds your user to the dialout group for console cable access
  4. Installs Python dependencies
  5. Creates the config directory /etc/switch-manager/
  6. Sets a static IP on your management network interface
  7. Asks whether to deploy with Docker (recommended) or native Python
  8. Guides you through console cable setup and software links
  9. Generates an ed25519 SSH keypair
  10. Shows you exactly what to paste on the switch console
  11. Tests the SSH connection and retries if it fails
  12. Pins the switch host key (MITM protection)
  13. Generates your TOTP authenticator secret with QR code
  14. Verifies your authenticator app is working before continuing
  15. Patches the backend config with your switch IP and credentials
  16. Builds the React frontend (requires Node.js)
  17. Installs and enables a systemd service (or Docker container)
  18. Starts the service
  19. Optionally sets up Docker with Caddy HTTPS
  20. Optionally configures WireGuard VPN for remote access
  21. Optionally installs Control D DNS filtering via ctrld

Re-running is safe — completed steps are skipped.


Deployment Options

The script explains both options before asking:

Docker + Caddy (recommended default) Runs the switch manager in a container with all dependencies baked in. Caddy provides automatic HTTPS at a hostname you choose (default: switch.mgmt.lan). Caddy generates its own internal CA — the setup script installs it into your system trust store automatically so browsers show a clean padlock. Updates with one command: docker compose pull && docker compose up -d.

Native Python (bare metal) Runs directly as a Python process managed by systemd. Simpler, lower memory, no Docker required. Access via http://IP:8765 directly. Right choice for very low memory machines or users who prefer managing services directly.


Accessing the Interface

http://[management computer IP]:8765

Or with Docker + Caddy:

https://switch.mgmt.lan

You must be on VLAN 99 (management VLAN) or connected via WireGuard VPN to reach this address. This is intentional — the switch enforces isolation at the network layer.

Getting onto VLAN 99 from your laptop

Linux:

sudo ip link add link eth0 name eth0.99 type vlan id 99
sudo ip addr add 192.168.99.50/24 dev eth0.99
sudo ip link set eth0.99 up

Mac: System Settings → Network → Add VLAN interface → VLAN ID 99

Dedicated port: Ask the switch to put one port on VLAN 99 as an access port. Plug in when managing.

VPN: Connect via WireGuard (configured during setup or via the VPN tab).


The Interface — Eight Tabs

Port Map

Visual 48+4 port chassis, colour-coded by VLAN. Each port shows its VLAN assignment, mode (access/trunk/disabled), and a green dot when PoE is active. Click any port to configure it in the right panel.

Port configuration panel:

  • Description (e.g. "AP-Corridor-1", "Camera-NE")
  • Mode: Access, Trunk, or Disabled
  • VLAN assignment (access) or tagged/native VLANs (trunk)
  • PoE on/off and wattage limit (copper ports, 1W30W)

Live status pulls from the switch every 15 seconds while the tab is active, 60 seconds when backgrounded, and pauses when nobody has the page open.

VLANs

Create, rename, and delete VLANs. Shows port count and subnet per VLAN. VLAN 1 cannot be deleted.

ACL Builder

Build Access Control Lists visually. Each rule specifies action (permit/deny), protocol (ip/tcp/udp/icmp), source, destination, and optional port. The ACL is assigned to a VLAN interface with a direction. The tool generates all CLI syntax — you never write it yourself.

Templates: Click "Use Template" to pre-fill rules for common patterns: Staff (full internet, no management), IoT (internet only, no RFC1918), Guest (internet + ctrld DNS enforcement), Camera (NVR only). All rules are editable after applying the template.

Review & Push

Every change across all tabs is translated into the exact CLI commands the switch understands. This tab shows those commands before anything is sent.

You never write CLI commands. The tool generates them. The review step exists so you can inspect what will be sent.

Push mode choice:

  • Batch — all commands sent in sequence, results shown when complete
  • Step by step — one command at a time, confirm each before the next is sent

Each command is displayed with a plain-English explanation of what it does and what it affects. You can read exactly what is about to happen.

Device Access

Manages which devices can reach the management interface from their normal VLAN without needing VPN. The switch enforces access via an ACL pinhole. TOTP still gates any changes.

MAC address randomization warning: Modern phones and laptops randomize MAC addresses per network. This breaks DHCP reservations. The tab shows per-platform instructions to disable it (iOS, Android, macOS, Windows) before adding a device.

Live DHCP leases pulled from the switch appear as unregistered devices — click Register to add them.

Per device:

  • Name, MAC, IP, VLAN
  • Reserve static IP (DHCP binding pushed to switch)
  • Grant/revoke management access (ACL pinhole pushed to switch)

DHCP

Unified view of all DHCP reservations across switch and OPNsense (if configured).

DHCP server recommendation:

  • Use switch DHCP for VLAN 99 (management) — devices get IPs before OPNsense is reachable
  • Use OPNsense for all other VLANs — integrates with DNS, firewall rules, lease history
  • Never run both for the same VLAN

OPNsense integration (optional): Auto-detects OPNsense at your gateway IP. If found, prompts for API key. Once connected, shows reservations from both switch and OPNsense in one table, colour-coded by source.

Conflict detection: If the same MAC has reservations in both places, a badge appears — red for IP conflicts (same MAC, different IP), yellow for duplicates (same MAC, same IP). Each conflict has a Resolve button with four options: Switch wins, OPNsense wins, Remove from switch, Remove from OPNsense.

DNS Filtering

Configures Control D DNS filtering per VLAN via the ctrld daemon.

How it works: ctrld runs as a local DNS proxy. Devices send normal DNS queries to it. ctrld identifies the source VLAN subnet and routes each query to the correct Control D profile via DoH3. Each VLAN gets different filtering rules. Your ISP sees encrypted HTTPS traffic, not DNS queries.

Three deployment options presented with full explanations:

Option A — ctrld on the management computer (fully automated) Installs ctrld alongside the switch manager. One command downloads and installs it, writes the per-VLAN config, starts it as a system service. The switch DHCP points each VLAN to this machine's IP for DNS.

Option B — ctrld on OPNsense (semi-automated) Generates a single SSH command to paste into OPNsense shell. ctrld installs as a service on OPNsense. OPNsense's IP becomes the DNS server for the network.

Option C — manual / existing setup Generates the ctrld.toml config and install command. You install wherever you choose.

Per-VLAN Resolver IDs: Each VLAN gets its own Control D profile. Enter the Resolver ID from the Control D dashboard (controld.com → Add Device → Router → Resolver ID). VLANs without a Resolver ID use the first configured profile as fallback.

DNS Enforcement: After installing ctrld, use the "Enforce DNS on Switch" button to generate ACLs that block devices from bypassing ctrld by using 8.8.8.8 directly. See DNS Enforcement ACLs below.

Local Hostnames: Optionally run a dnsmasq container so .lan names resolve for all devices. See Local Hostname Resolution below.

References:

VPN

Manages WireGuard VPN for remote access to the management interface from outside the management VLAN.

Add clients: Enter a name (laptop, phone, tablet) and the tool generates a keypair, adds the peer to the server config, reloads WireGuard live, and displays a QR code to scan with the WireGuard app. Also saves a .conf file for desktop import.

Revoke clients: Disconnects the peer immediately and removes it from the server config.

Connected peers: Shows last handshake time and transfer stats for each peer.

SSH tunnel alternative: For power users — one command gives secure access without WireGuard installed:

ssh -L 8765:localhost:8765 user@management-computer-ip

Making Changes — Step by Step

  1. Configure across any tabs — nothing happens on the switch yet
  2. Go to Review & Push — read the generated commands with explanations
  3. Check for dangers — automatic pre-flight runs before authentication
  4. Authenticate — enter 6-digit TOTP code to unlock a push session
  5. Choose push mode — batch (faster) or step-by-step (full control)
  6. Push — commands go one at a time, checked after each
  7. Review results — each command shows success or failure with the switch's error output
  8. Auto-lock — session closes when push completes. New changes need a new TOTP code

Authentication and Sessions

Read-only — no authentication required. Anyone on VLAN 99 can view the dashboard.

Push mode — requires TOTP. One code unlocks exactly one push session. The session closes automatically when the push completes or you cancel. The next set of changes requires a new TOTP code.

Why TOTP and not a password: VLAN 99 isolation is the primary barrier. TOTP adds a second factor confirming it is you making a change. A code is useless after 30 seconds and requires physical access to your authenticator app.


How Commands Reach the Switch

Exact sequence on every push:

  1. Browser sends the command list to the management computer backend
  2. Backend runs a danger check against known lethal patterns
  3. Backend validates every command against an allowlist
  4. Backend opens a fresh SSH connection using the ed25519 key stored on the management computer
  5. Commands execute one at a time via interactive shell
  6. After each command the switch's response is checked for error patterns
  7. On error: push stops immediately, no further commands sent, config not saved
  8. On full success: end then copy running-config nvram:config.cfg — config saved to NVRAM

Blocked Commands

Hard-blocked — refused entirely, must run at the switch console:

Pattern Reason
no vlan 99 Deletes management VLAN
vlan members remove ... 99 Removes VLAN 99 from a port — kills management trunk
no vlan tagging ... 99 Removes VLAN 99 tagging — kills management trunk
no ip ssh Disables SSH — permanent lockout
no ip address Removes IP — management computer loses connectivity
interface vlan 99 Modifies management VLAN interface
boot config flags factory Factory reset

Warning-level — shown for review, push proceeds with confirmation:

Pattern Reason
shutdown Shuts down an interface — confirm not your uplink
default interface Resets interface to defaults
no vlan [id] Deletes a VLAN — confirm no active ports depend on it
spanning-tree ... disable Disables spanning tree — loop risk

SSH Key Security

The ed25519 private key lives at /etc/switch-manager/ers5952_key on the management computer. It never leaves that machine. Your laptop, phone, or tablet never touches it.

The switch host key is pinned after the first connection. If the switch's host key ever changes the backend refuses to connect and reports the mismatch — MITM protection even on the management VLAN.


Console Cable

See Physical Setup — First Time Out of the Box above for the complete walkthrough including where the console port is, what cable to buy, and what to do at the boot screen.

The short version: one-time only, RJ-45 to USB console cable (~$8), 9600 baud, no parity.

Switch password rules: 832 characters. Special characters allowed: ! @ # $ % ^ & * - _ = + [ ] ; : , . /. No spaces. No quotes.


Live Polling

The backend polls the switch using a connection pool:

  • Pool lifetime: 25 seconds (shorter than switch idle timeout)
  • Tab active/visible: polls every 15 seconds
  • Tab backgrounded: polls every 60 seconds
  • No visitors for 5 minutes: polling pauses completely
  • New visitor opens page: immediate poll, resumes normal interval

The switch is never being polled when nobody is looking at the dashboard.


Files Created

File Location Purpose
switch_backend.py Project folder Python API server (34 endpoints)
ers5952-manager.jsx Project folder React app source (8 tabs)
README.md Project folder This file
Dockerfile Project folder Docker image definition
docker-compose.yml Project folder Caddy + switch manager services
Caddyfile Project folder HTTPS reverse proxy config
ctrld.toml Project folder Control D per-VLAN DNS config (if configured)
frontend/dist/ Project folder Built React app
ers5952_key /etc/switch-manager/ SSH private key (chmod 600)
ers5952_key.pub /etc/switch-manager/ SSH public key
known_hosts /etc/switch-manager/ Pinned switch host key
totp_secret /etc/switch-manager/ TOTP seed (chmod 600) — back this up
devices.json /etc/switch-manager/ Registered device list
opnsense.json /etc/switch-manager/ OPNsense API credentials (chmod 600)
ctrld.json /etc/switch-manager/ Control D config (chmod 600)
wg_server_private /etc/switch-manager/ WireGuard server private key (chmod 600)
wg_server_public /etc/switch-manager/ WireGuard server public key
clients/ /etc/switch-manager/ WireGuard client .conf files
switch-manager.service /etc/systemd/system/ Systemd service (native mode)
local-hostnames.json /etc/switch-manager/ User-defined hostname→IP mappings (optional)
dnsmasq.conf /etc/switch-manager/ Generated dnsmasq config (optional)

Back up /etc/switch-manager/totp_secret — if the management computer fails and you have not backed this up you will need to regenerate the TOTP secret and re-scan it into your authenticator app.


Troubleshooting

Connection banner stuck on "Connecting..." Backend not running or device not on VLAN 99. Check: sudo systemctl status switch-manager or docker compose ps

"Switch unreachable" in status pill Backend running but cannot reach switch. Check: ping 192.168.99.1 from the management computer.

TOTP code rejected Ensure time is synchronised on both the management computer and your phone. Backend allows one 30-second window of clock drift. Sync: sudo timedatectl set-ntp true

Command failed — switch error shown Read the error text — the switch says exactly what was wrong. Fix the configuration and push again. Already-succeeded commands do not need to be resent.

Host key rejection after switch reset Re-pin: ssh-keyscan -H 192.168.99.1 > /etc/switch-manager/known_hosts

ctrld not filtering DNS Check DHCP option 6 is set to the ctrld machine's IP on each VLAN pool. Check ctrld is running: ctrld status. Check the switch is handing out the right DNS: from a device, run nslookup example.com and verify the server IP matches.

WireGuard not connecting Check port 51820 UDP is reachable from outside your network (router port forwarding may be needed for external access). Check: sudo systemctl status wg-quick@wg0

Service logs

# Native
journalctl -u switch-manager -f

# Docker
docker compose logs -f
docker compose ps

What This Tool Does Not Do

  • Does not manage OPNsense, pfSense, or any other device directly (OPNsense integration is read/sync only)
  • Does not provide a terminal or shell — there is no way to type arbitrary commands through the main interface (CLI mode in settings is available for advanced users but still runs through the safety pipeline)
  • Does not support multiple switches simultaneously
  • Does not provide traffic analytics or bandwidth graphs
  • Does not automatically discover or adopt new network devices

On the ERS Switch Family

These switches have no REST API. Everything this tool does is via SSH sessions that parse text output and send CLI commands — the same thing a human would do at a terminal, automated and wrapped in a browser interface.

There is an inherent limit to how reliably the tool can detect every possible error condition. The danger blocking system catches the known lethal patterns but cannot anticipate every possible misconfiguration. Use the CLI review step. Read what is about to be sent.

The console cable is always your fallback. Keep it accessible.


DNS Filtering — Port 53 Conflict Resolution

When installing ctrld (Option A — local install), ctrld needs to bind port 53. On Ubuntu and Debian, systemd-resolved holds port 53 via its stub listener.

The tool fixes this automatically during installation. It adds DNSStubListener=no to /etc/systemd/resolved.conf and restarts systemd-resolved. The service itself keeps running — it still manages /etc/resolv.conf and local hostname caching. Only the stub listener is disabled.

If the automatic fix fails (permission issue, non-standard config), fix it manually:

echo "[Resolve]" | sudo tee -a /etc/systemd/resolved.conf
echo "DNSStubListener=no" | sudo tee -a /etc/systemd/resolved.conf
sudo systemctl restart systemd-resolved

On OPNsense (Option B): OPNsense runs Unbound DNS on port 53. The correct approach is not to uninstall Unbound — it handles .lan hostnames and local DNS. Instead:

  1. In OPNsense UI: Services → Unbound DNS → General → set Listen Port to 5353, Listen Interface to Loopback (lo0). Save + Apply.
  2. Configure ctrld to forward *.lan and *.local to 127.0.0.1:5353 (the split-horizon block shown in the DNS tab result panel).
  3. ctrld handles all other queries via DoH3 to Control D.

This keeps local names working while all external DNS is filtered per-VLAN through Control D.


DNS Enforcement ACLs

Without enforcement, a device can ignore DHCP-assigned DNS and use 8.8.8.8 directly, bypassing all ctrld filtering.

The DNS tab has an "Enforce DNS on Switch" button that generates ACLs blocking this. For each VLAN:

ip access-list extended DNS-ENFORCE-VLAN10
  1 permit udp 192.168.10.0 0.0.0.255 host [ctrld-ip] eq 53
  2 permit tcp 192.168.10.0 0.0.0.255 host [ctrld-ip] eq 53
  3 deny   udp 192.168.10.0 0.0.0.255 any eq 53
  4 deny   tcp 192.168.10.0 0.0.0.255 any eq 53
  5 deny   tcp 192.168.10.0 0.0.0.255 any eq 853
  6 permit ip any any
interface vlan 10
  ip access-group DNS-ENFORCE-VLAN10 in

Rules 12 permit DNS only to ctrld. Rules 34 block DNS anywhere else (8.8.8.8, Cloudflare, etc.). Rule 5 blocks DNS-over-TLS (port 853) as another bypass path. Rule 6 permits all other traffic so internet still works.

VLAN 99 (management) is automatically excluded — a broken ACL on the management VLAN would lock you out.

The generated commands are shown for review and pushed through the normal TOTP-gated push mechanism. Nothing is sent to the switch automatically.


Inter-VLAN Routing ACL Templates

The ACL Builder tab has a "Use Template" button that pre-fills common policies:

Staff VLAN — full internet, no management access Permits everything except access to VLAN 99 (192.168.99.0/24). Use on a staff or office VLAN where users need full internet but must not reach the management interface.

IoT VLAN — internet only, no RFC1918 Blocks all RFC1918 private address ranges (192.168.x.x, 10.x.x.x, 172.16-31.x.x). IoT devices get internet but cannot reach any other VLAN, internal servers, or management. Permits internet.

Guest VLAN — internet only, DNS must work first Like IoT but explicitly permits DNS to ctrld first (before the deny rules), ensuring DNS filtering continues to work even after RFC1918 is blocked.

Camera VLAN — NVR only Cameras may only send traffic to one NVR/DVR IP. All other traffic is dropped. Prevents cameras from phoning home, scanning the network, or accessing the internet directly.

All templates are fully editable after applying. The template fills the rule table — you adjust IPs, add rules, or delete rules before pushing.


Local Hostname Resolution (dnsmasq)

The DNS tab has a "Local Hostnames" section. It manages an optional dnsmasq container that resolves .lan hostnames for all devices on the network.

How it works:

  1. dnsmasq runs in Docker, listening on port 5353 on the management computer.
  2. ctrld is configured to forward *.lan and *.local queries to 127.0.0.1:5353 (split-horizon rule).
  3. All other queries go through Control D as normal.
  4. switch.mgmt.lan and management.lan always resolve to the management computer's IP.

Setup:

Add hostname→IP mappings in the DNS tab → Local Hostnames section. Click Save & Generate dnsmasq.conf. The tab shows:

  • The generated dnsmasq.conf content and path
  • A docker-compose snippet to add the dnsmasq service
  • A ctrld.toml block to enable split-horizon forwarding

Add the docker-compose snippet to docker-compose.yml, add the toml block to ctrld.toml, then:

docker compose up -d dnsmasq
ctrld restart

The dnsmasq.conf is written to /etc/switch-manager/dnsmasq.conf and mounted read-only into the container.

Files added:

File Location Purpose
local-hostnames.json /etc/switch-manager/ User-defined hostname→IP mappings
dnsmasq.conf /etc/switch-manager/ Generated dnsmasq config
S
Description
Mirror of outis1one/avaya_switch_management from GitHub
Readme
522 KiB
Languages
Python 69.4%
JavaScript 28.7%
Shell 1.9%