How We Built a Browser-Based Cyber Range
The technical decisions behind OdiVex's ephemeral lab infrastructure — containers, networking, and reset automation at scale.
The Problem With Traditional Labs
Training environments for offensive security have historically involved either expensive on-premise hardware rigs or slow-to-provision cloud VMs. Neither scales well, neither resets cleanly, and neither is accessible from a browser on a flight.
We wanted something different: a lab that spins up in under 10 seconds, costs pennies per session, resets to a clean state with zero manual intervention, and runs entirely in a browser tab.
The Architecture
Ephemeral Container Networks
Each user session gets an isolated network namespace — a private /24 subnet with no connectivity to other users or the internet. We use Linux network namespaces, veth pairs, and nftables for routing and isolation.
The "target" machine is a pre-built container image with deliberate vulnerabilities baked in. These images are immutable. When a session ends, the containers are destroyed, not stopped.
The Browser Terminal
We built a WebSocket-based PTY (pseudo-terminal) multiplexer using xterm.js on the frontend and node-pty on the backend. The connection goes: Browser → WebSocket → container exec → shell. Latency is typically under 30ms for users within region.
Snapshot-Based Reset
Rather than rebuilding containers from scratch on reset, we use OverlayFS to layer a clean "upper" directory on top of a read-only "lower" base. Reset means: unmount the upper layer, create a new empty upper. The base image is never touched.
This makes resets instant and storage-efficient — hundreds of users can share one base layer.
What We Learned
- Kernel version matters — cgroupv2 behavior differs significantly between kernel 5.15 and 6.1
- WebSocket keepalives are not optional — without active keepalives, load balancers will terminate idle connections
- Browser-initiated clipboard access requires HTTPS — testing over HTTP breaks clipboard integration
- Don't expose the Docker socket — ever. Use a privilege-separated orchestration daemon.
What's Next
We're moving to a model where the entire network topology is defined as code and stored per-exercise. Want a lab with an AD forest, a web app, and a CI/CD pipeline? That becomes a YAML file that provisions in 30 seconds.