/ws/monitor /ws/terminal /ws/customer

Container isolation lab

Show the exploit, then show the boundary.

A three-container playground that stays intentionally vulnerable. You trigger payloads from dokuru-lab-baseline, and Dokuru changes what that container can see and how much it can consume — without rewriting the app.

or jump to scenarios

The setup

Three Docker containers, one shared kernel

01

Attacker

dokuru-lab-baseline

The vulnerable web app. You trigger every payload from inside this container — cryptominer, memory blast, secret theft, proxy sabotage.

02

Neighbor

victim-checkout

A second container Dokuru must protect. Holds POSTGRES_PASSWORD and serves a checkout API that should keep responding through every blast.

03

Signal

customer-traffic

An out-of-band probe that hits the neighbor on a loop. Its latency feed becomes the customer truth in Customer Live View.

signal measures blast radius after every payload

01 Blast radius

Trigger a payload, watch the neighbor

Each scenario runs from inside dokuru-lab-baseline. Open the terminal sidebar to follow stdout/stderr while the customer signal updates live.

Customer Live View

waiting for stream

Real customer path

waiting
no data
waiting for /ws/customer...
Average
...
Failures
0
Samples
0
Source: direct-probe

Latency is sampled by the customer-traffic sidecar hitting the neighbor victim-checkout. Even when the attacker lab steals CPU or memory, this signal originates from a separate container so blast radius is observable end-to-end.

Blast-radius scenarios

Lab v2
Baseline customer

Probe victim-checkout directly to confirm the neighbor service is healthy before any payload runs.

B1 Cryptominer

Saturate available CPU cores with short-lived miners. Watch Active burners and customer latency when no CPU quota is configured.

B2 Memory blast

Start a child process that holds 1280 MiB. Use Stop payload to terminate it; with rule 5.11, only that process is OOM-killed.

B3 Secret theft

Locate the postgres neighbor PID and read /proc/<pid>/environ to leak POSTGRES_PASSWORD.

B4 Reverse-proxy sabotage fallback

Send SIGSTOP to the host caddy process — the lab UI disconnects briefly until an automatic SIGCONT resumes it. Use as a fallback only.

02 Live monitor

Real-time namespace and cgroup signals

Streamed over /ws/monitor straight from dokuru-lab-baseline. See the exact limits and isolation status below.

Live resource monitor

WebSocket reconnecting
Process Limits Rule 5.29: Restrict PIDs
... / ...

PID sleepers: 0. Run PID bomb and watch this climb.

Memory Sandbox Rule 5.11: Memory Quota
unavailable
Memory limit unavailable
CPU Throttling Rule 5.12: Core Isolation
Quota status
Configured
cpu.weight
...
cpu.max
...
Active burners
0
Namespace Reality Rules 5.16, 5.17, 5.21, 5.31
UID Mapping (User NS)
loading
PID Boundary
loading
Total processes visible
...

03 Namespace isolation

Prove what the container can see

CIS Docker Benchmark rules 2.10, 5.16, 5.17, 5.21, 5.31. Capture proof output before and after Dokuru recreates the container.

Namespace proof

Rules 2.10, 5.16, 5.17, 5.21, 5.31
UID remap

uid_map starts as 0 0. After Dokuru userns-remap, root maps to a host subuid.

PID namespace

Before hardening, host processes are visible. After the fix, the process list is container-scoped.

Namespace links

Compare /proc/self/ns/* before and after Dokuru recreates the container.

04 Cgroup controls

Prove how much the container can consume

CIS Docker Benchmark rules 5.11, 5.12, 5.29. Tune inputs, run pressure, then read the live monitor while Dokuru applies mem_limit, cpu_shares, and pids_limit.

Cgroup pressure

Rules 5.11, 5.12, 5.29
Processes
Allocation

Starts a child process that holds memory until Cleanup or Stop payload.

Scheduler
Cleanup

Kill sleeper, CPU, and memory pressure processes to reset the environment.

05 Evidence

Side-by-side reference for the report

Side-by-side comparison of container isolation. The application remains vulnerable, but the blast radius is strictly contained.

Runtime evidence

Check

Runtime snapshot of the container's isolation boundary — which user identity it holds, which namespaces it's confined to, and whether resource limits are actively enforced.

User
loading
Userns
loading
cpu.weight
loading
cpu.max
loading

Before / after proof

Isolation comparison

Observable differences before and after Dokuru applies container hardening rules. The application workload remains unchanged; only the isolation boundary shifts.

Before After
UID map
0 → 0 (root = root)
0 → 4294967295 (remapped)
PID view
host process list visible
only container processes
PIDs
unlimited — bomb spawns freely
pids.max caps the bomb
Memory
unlimited / host-sized
explicit memory limit set
CPU
default shares (unthrottled)
explicit cpu.weight set
Inspect baseline docker inspect dokuru-lab-baseline
Dokuru Namespace & Cgroup Lab
Run only on a disposable lab host. Endpoints intentionally expose shell execution and resource pressure.