When the vendor stopped supporting the hardware before the cipher suites were updated, the official path is gone. The hardware still works fine — you just have to meet it on its own terms.Older enterprise server BMCs (out-of-band management controllers — Dell iDRAC 6, HPE iLO 3, Supermicro IPMI 1.5 era) shipped with web consoles designed around contemporary Java Web Start, ActiveX, and TLS cipher suites. A decade later, every modern browser refuses the plugins, every modern JRE refuses the unsigned jars, and every modern TLS stack refuses the ciphers. The chassis is still on the rack, still drawing power, still perfectly usable — and the official remote-management story is gone. This page captures the patterns that keep us working on this gear without a VGA monitor and without lowering the security posture of our daily-driver workstation.
Pattern 1 — Reverse-engineer the hidden HTTP API
Before fighting the Java applet, look at what its parent web UI is doing over plain HTTP. Open the BMC web UI in a modern browser, accept the self-signed cert, open the network panel, and watch. What you almost always find:- A login endpoint (often
POST /data/loginor similar) that returns session tokens plus a cookie - Combined “system summary” endpoints that batch a dozen sensor and state fields in one XML payload
- A screen-capture endpoint the web UI hits every few seconds to refresh its tiny preview pane — this is the same VGA buffer the expensive Java applet would render at full resolution
curl
calls (trigger refresh, fetch PNG) replace the entire Java vKVM stack
for monitoring purposes.
A typical recipe:
curl and a PNG.
Why this is safe to publish
We are not publishing exploits. The endpoints are reachable to anyone already authenticated to the BMC. The vendor knows about them — their own web UI calls them. We are publishing how to discover that the endpoints exist so AI agents and homelab operators can build better monitoring tools instead of forcing brittle Java applets onto modern workstations.Pattern 2 — Wrap the Java applet, do not replace it
When you do need interactive vKVM and the only path is the BMC’s unsigned Java applet:- Don’t install Java on the host workstation. Put the whole legacy Java stack inside a single throwaway container.
- Inside that container, run a desktop environment streamed to the
browser (e.g.
linuxserver/webtopfor an XFCE-in-browser experience). - Install OpenWebStart, JRE 8, and a
jarsigner-capable JDK headless into that container. - Intercept the
.jnlpdownload with a small wrapper script that:- Downloads each jar referenced by the JNLP
- Strips any pre-existing signature blocks
- Re-signs every jar with a container-local self-signed keystore
- Rewrites the JNLP’s jar URLs to point at the locally re-signed
copies on disk via
file:// - Hands the rewritten JNLP to
javaws
- Register the wrapper as the system MIME handler for
application/x-java-jnlp-fileso the workflow is one-click from the BMC web UI inside the container.
- BMC firmware updates can rotate the jar set; the wrapper’s jar-signing cache needs to be invalidated when that happens
- JNLP files generated by legacy BMCs sometimes URL-encode spaces as
+in the canonical-href attribute. Modern Java URL parsers round-trip-decode that to space and look for a file that doesn’t exist. The wrapper has to strip that attribute before passing tojavaws. - The BMC’s video-encryption setting (often RC4) silently breaks the KVM connect on modern Java TLS stacks. If the BMC is on a trusted out-of-band VLAN, disable it.
Pattern 3 — Headless installs on hardware without VGA
For installing a modern OS onto a chassis where:- The Java vKVM is broken (see Pattern 2)
- No VGA cable or monitor is available
- No serial console cable is on hand
-
Build a custom installer ISO with an embedded answer file (Proxmox’s
proxmox-auto-install-assistant, Debian preseed, RHEL kickstart — every distro has the equivalent). The answer file must specify network from DHCP and a known SSH key. - Drop the ISO onto a multi-boot USB stick (Ventoy works well) and configure the stick’s bootloader to auto-pick the installer with a short timeout — no keyboard required.
-
Use IPMI to force one-shot boot from removable media:
Note: in IPMI spec parlance,
floppymeans “USB stick” on modern hardware — the spec predates USB.cdromroutes to optical drives or virtual-CD subsystems (the latter is broken on a lot of legacy BMCs, which is why USB-boot is the reliable path). - Monitor progress via the Pattern 1 screenshot loop — every minute, grab the PNG, compute its hash, alert on change. The installer takes 15-30 min on legacy USB 2.0; you’ll see GRUB, then the automated installer log, then a login prompt.
- Detect completion by polling SSH on the expected IP. When the port opens, the install succeeded.
Pattern 4 — PXE-boot as the override of last resort
When USB-boot keeps falling through to the wrong OS on internal disks (legacy BMCbootdev=floppy options=persistent is silently one-shot
on many firmwares — the override is consumed on the next boot, then
BIOS falls through to the default disk priority), PXE is the
reliable last-mile remote install path:
- Stand up
dnsmasqin proxyDHCP mode on a host that already sits on the target VLAN (we use the existing healthy hypervisor).--dhcp-no-override --dhcp-range=<subnet>,proxysupplements the existing gateway’s DHCP with PXE options only, without conflicting.--port=0disables the DNS half so it doesn’t clash with the site’s real resolver. - Build a custom iPXE binary with an
EMBED=script baked in. Most distro packages of iPXE do not auto-execute the DHCP-offered bootfile URL when chainloaded from BIOS PXE — iterating on dnsmasq config alone will never make iPXE chain. Embedding the script insideundionly.kpxemakes the chain deterministic, with no external fetch dependency. - Boot kernel + initrd directly via iPXE, not the ISO via
sanboot. sanboot of a large auto-install ISO is unreliable on
pre-2010 server NICs and BMC video stacks. Extracting the kernel
and initrd from the ISO (
mount -o loopthen copyboot/linux26+boot/initrd.img) and serving them via HTTP is small (~70 MB), bursty but reliable. - Pass the answer-file URL on the kernel cmdline. Modern Linux installers (Proxmox VE’s auto-installer, Debian preseed, RHEL kickstart) accept fetch URLs as kernel parameters. The installer’s first network-up step fetches the answer file over HTTP and proceeds unattended.
bootdev=pxe options=persistent plus a
power-cycle. The “persistent” keyword is still ignored on legacy
BMCs, but PXE doesn’t have the same fall-through-to-disk-OS problem
that USB does — if the PXE server is reachable, the install
proceeds; if not, the chassis simply hangs at “PXE boot failed”,
which is observable from the BMC screen-capture and IPMI sensor
data.
What we learned along the way
- Reach for plain HTTP first. The fancier protocol — Java applet, vendor-specific SDK, OEM thick-client tool — exists to ship features the vendor wanted to sell. The actual data almost always flows over plain HTTP underneath. The plain HTTP path is older, simpler, and far more likely to still work when the vendor has moved on.
- Isolate the legacy stack at the container boundary. When you do
need to keep the legacy plugin alive, put it inside a container that
can be
docker compose down -v’d cleanly. Don’t pollute the host workstation with year-old Java and downgraded TLS ciphers. - The IPMI spec is old enough to vote. Read its glossary before
trusting any field name.
floppyis USB,cdromis optical-or-vCD,pxeis BMC-mediated network boot. Mismatches between modern intuition and 1998-era terminology eat hours. - Document the API as you discover it. Each endpoint you reverse-engineer gets entered into a per-BMC API reference in the private companion docs. The next AI agent that needs to monitor this hardware should not have to rediscover the same endpoints from scratch.
Related
- Infrastructure overview — the modern hardware story this hardware is being added to.
- Conventions / no scripts — the bias toward one-liners over shell scripts; the workarounds above are kept to that bar where possible.