Skip to main content

Half a management plane, and the one door that fixed it

·511 words·3 mins

I had a VLAN 10 called “Management.” It held the switch’s and the access point’s management addresses, and the gateway. Tidy. Then I asked an obvious question: where do the actual servers get managed? — and the answer was “on whatever VLAN they happen to live in.” The management VLAN managed the network gear but not the boxes I SSH into. It was half a management plane.

Making it whole
#

Option A was to leave it as “network gear only” and keep managing hosts on their service VLANs. Option B was to make VLAN 10 the real management plane: every serious host gets a management address there, and that’s where administration happens.

I took B — but with one non-obvious choice about routing.

The default route stays on the service VLAN, not the management VLAN. That’s counterintuitive for a “management plane,” but it’s better: the latency-sensitive services (like NTP) sit on the default leg and stay symmetric, while only admin SSH takes the source-routed/VRF path. And it keeps the management VLAN cleanly no-internet — host updates flow through an internal package cache instead. Management traffic and data traffic are genuinely separated.

There’s a nice consequence: for a Proxmox host that serves nothing cross-VLAN, its management IP is effectively its identity, and everything else (its guests) route themselves.

The one door: a bastion
#

Here’s the part that surprised me — adding a jump host tightened the firewall rather than adding holes.

The naive way to let my laptop (on the client VLAN) manage the server VLANs is to allow clients → servers:22, clients → infra:22, clients → dmz:22… SSH holes scattered across every segment, exposed to every client. Instead:

  • One hardened bastion on the management plane.
  • clients → bastion:22 — the single cross-VLAN management path.
  • bastion → everything:22 — the bastion reaches the rest.

That’s fewer rules and one audited choke point. My SSH config and my automation both ProxyJump through it, so ssh <any-internal-host> transparently hops via the bastion. Web UIs (like the hypervisor console) go through an ssh -L tunnel — so there’s no direct “clients → management web” hole either.

The trade-offs I wrote down
#

  • The bastion is a management single point of failure — but not a service one. If it’s down, workloads keep running; I just console in via the hypervisor to fix it.
  • It’s the crown-jewel entry point, so it gets extra hardening (fail2ban now; a proper SSH CA and MFA later). One door means one door to watch well.
  • A jump host only helps if forwarding is allowed on it — standard SSH hardening disables X11 forwarding but not TCP forwarding, so ProxyJump keeps working. I pin that explicitly anyway, so a future hardening tweak can’t silently lock me out.

What I’d tell past-me
#

  • A “management VLAN” that doesn’t hold your servers’ management is decoration, not a plane.
  • Counter-intuitively, funnelling management through one bastion makes the firewall smaller and clearer — not bigger.
  • Decide which leg is the default route deliberately; it determines which services stay symmetric and which need source-routing.