Hardening the HP 2530 Switch and Chasing a Routing Bug Over Tailscale
I picked up a used HP 2530-24G-PoE+ for not much money, mostly because I wanted my lab traffic to look like it was actually going through something, not just fanning out from a flat home router. It arrived in genuine factory-default state, no manager password, default SNMP community wide open, VLAN 1 still sitting on DHCP. Before touching anything I ran show running-config to confirm that for myself instead of trusting the listing description. One thing threw me off during that first console session: the login banner showed a “previous successful login” entry as manager, on a switch that had clearly never been touched. Turns out that’s expected. HP’s ProVision software grants Manager-level console access by default whenever no manager password exists, and logs that as a login. Not evidence of a prior owner’s leftover credentials, just how the platform behaves out of the box.
The hardening pass itself was mostly what you’d expect. Pulled the default SNMP community with no snmp-server community "public", careful with the syntax since the unrestricted keyword throws an error in the no form and the bare community name is what actually works. Set a static management IP on VLAN 1, and had to remember to set the default gateway again by hand afterward, since switching from DHCP to a manual address drops whatever gateway DHCP had populated. Set a manager password. Enabled SSH, disabled Telnet, no argument there, cleartext management isn’t real security even inside a segmented network.
The clock was its own small fight. These switches have no battery-backed RTC, confirmed against HPE’s own documentation, so without SNTP configured the clock resets to January 1990 on every reload. I pointed it at a public NTP server and got an “Invalid IP address” error on the first attempt, which turned out to be the switch’s own parser rejecting any address ending in .0 as a network identifier rather than a host, even for a legitimate server. A sibling address on the same provider worked fine.
Firmware was the last piece, and the biggest jump: whatever had shipped on this thing back in 2013, brought current. I did it the careful way, loading the new image to the secondary flash slot and leaving primary untouched as a rollback path, using a TFTP server I stood up on Proxmox specifically for the transfer. Before starting I checked whether the version I was moving to sat inside a known bad window, a documented signature-verification bug that broke TFTP uploads on a narrow band of firmware builds. My starting version predated that window by enough that the switch doing the verification during the upload wasn’t the buggy one, so it went through clean on the first attempt. The jump was big enough to also trigger automatic BootROM and PLD upgrades mid-boot, with explicit do-not-interrupt warnings and two extra reboots. Normal for a gap this size, not a sign anything broke.
With the switch itself squared away, I wanted to manage it remotely without punching a hole in my home router for it. Proxmox already sits on the home LAN, so I gave the Proxmox host its own Tailscale identity rather than routing switch traffic through the lab subnet’s own gateway VM. Scoped it with tags instead of leaving Tailscale’s default wildcard policy in place, since a single-owner tailnet with every device signed in under the same identity doesn’t get any real restriction from ownership-based rules. Tags are the actual mechanism for saying which of my own devices can reach a sensitive node. Proxmox advertises a narrow /32 route to just the switch’s management IP, not the whole home subnet, and its own host firewall only allows the management ports from the LAN and from Tailscale’s CGNAT range, plus ICMP from the LAN for basic health checks. Anything not on that list gets dropped.
Getting the firewall rules live without locking myself out took a specific order: add and enable the allow rules first, then the cluster-wide firewall switch, then the host’s own enable toggle, then test every access path immediately rather than trusting that it worked. Proxmox has a built-in exception for local LAN traffic to its own management ports even under a drop policy, which is a real safety net, but it explicitly doesn’t extend to anything routed or tunneled, so Tailscale access needed its own rule or it would have gone dark the moment the policy flipped.
The genuinely interesting problem showed up after all of that was done, when I tried reaching the switch’s management IP from my laptop while sitting on the same physical LAN as the switch. Ping and SSH both timed out. Spanning tree looked fine. ARP wasn’t stale. A second vantage point from Proxmox itself reached the switch without issue, which ruled the switch out and pointed the finger squarely at something specific to my laptop’s own path. route print on the laptop showed the answer: the /32 route Proxmox was advertising over Tailscale was more specific than my laptop’s own /24 route to the same subnet over WiFi, and in longest-prefix-match routing, more specific wins regardless of whether that’s actually the sensible path. My own machine was routing traffic to a switch sitting a few feet away through a VPN tunnel.
Fixing it took two changes, not one. A persistent static route pinning that specific address back to the LAN gateway wasn’t enough on its own, because Windows stacks the WiFi adapter’s own automatic interface cost on top of whatever metric you set manually, and that automatic cost was high enough to still lose. The adapter’s own metric had to be pinned down directly before the static route actually won in the active routing table. Once both were in place, the LAN path took over, and the fix is self-healing by design, since the static route only activates when the gateway is actually reachable over WiFi, meaning it falls away cleanly the moment I leave the home network and Tailscale’s route takes over with nothing to remember or toggle by hand.
Sitting on the same subnet as a device doesn’t guarantee your traffic actually takes that path once something else on your machine has a more specific route to offer. That’s easy to say and apparently not that easy to remember mid-troubleshoot, since ruling out the switch itself took longer than it should have before the routing table gave up the real answer.