🚫 Ad Blocker Detected

Please disable your AD blocker to continue using this site. Ads help us keep the content free! please press keyboard F5 to refresh page after disabled AD blocker

請關閉廣告攔截器以繼續使用本網站。廣告有助於我們保證內容免費。謝謝! 關閉後請按 F5 刷新頁面

0%

RustBox - Docker-Lite Sandbox for Hackers and Learners

RustBox

A Docker-like container runtime written in Rust with daemon architecture, supporting multi-container orchestration, persistent state management, and comprehensive CLI commands.

Overview

RustBox is a container runtime that isn’t competing with (Docker or Kubernetes), we return to the core and build a simplest “Sandbox/isolated runtime environment” from the lowest level Linux kernel mechanisms (namespaces, cgroups, OverlayFS, etc.), provides Docker-like functionality using:

  • Daemon Architecture with Unix domain socket communication
  • Multi-container Management with persistent state
  • OverlayFS for isolated container filesystems
  • Cgroups v2 for resource limits (memory, CPU)
  • Linux namespaces for complete process isolation
  • Comprehensive CLI with run, stop, list, inspect, remove, logs, and attach commands

This tool is designed for container orchestration, testing environments, and secure code execution.

Architecture

Daemon-Client Model

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
┌──────────────────────────────────────────────────────────────────────────────┐
│ RustBox Architecture │
└──────────────────────────────────────────────────────────────────────────────┘

[rustbox CLI] [rustboxd Daemon]
│ │
│ Unix Socket │
│ /tmp/rustbox-daemon.sock │
│ │
│ IPC Protocol (JSON messages) │
│ ───────────────────────────────────────────▶ │
│ Commands: │
│ • run │
│ • stop │
│ • list │
│ • inspect │
│ • remove │
│ • logs │
│ • attach │
│ ▼
│ ┌────────────────────────────┐
│ │ Container Manager │
│ │ ───────────────────────── │
│ │ • Controls lifecycle │
│ │ • Creates sandbox env │
│ │ • Manages PTY + process │
│ └────────────────────────────┘
│ │
│ ▼
│ ┌────────────────────────────┐
│ │ Registry (HashMap<ID, Container>)│
│ └────────────────────────────┘
│ │
│ ┌────────────────────────────────────────────┐
│ │ Container Instances │
│ └────────────────────────────────────────────┘
│ │ │ │
│ ▼ ▼ ▼
│ [Container 1] [Container 2] [Container N]
│ │ │ │
│ ┌──────────────────────────────────────────────┐
│ │ Sandbox Components │
│ │ overlayfs + cgroups + namespaces │
│ └──────────────────────────────────────────────┘
│ │
│ │
│ (When attaching) │
│ ───────────────────────────────────────────────────────────────────────────
┌─────────────────────────────────────────────────────────────────────────────┐
│ Container Attach Flow │
└─────────────────────────────────────────────────────────────────────────────┘

Client (e.g. docker attach, CLI, web terminal)

1. Send/receive stdin/stdout over Unix socket

┌───────────────────────────────────────────────────────────┐
│ Daemon Process │
│ ───────────────────────────────────────────────────────── │
│ • Manages container lifecycle │
│ • Holds PTY master side │
│ • Forwards data between client and container
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Unix Socket (Client ↔ Daemon) │ │
│ │ - AttachStdin (client → daemon) │ │
│ │ - AttachStdout (daemon → client) │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ │ (I/O forwarding loop)
│ ▼
│ ┌──────────────────────────────────────────────────────┐ │
│ │ PTY Master │ │
│ │ - Pseudo terminal device endpoint controlled by │ │
│ │ the daemon │ │
│ │ - Reads container output │ │
│ │ - Writes client input │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ │ (kernel-level link)
│ ▼
│ ┌──────────────────────────────────────────────────────┐ │
│ │ PTY Slave │ │
│ │ - Exposed inside the container as /dev/tty or stdin │ │
│ │ - Attached to the container’s process (e.g. /bin/bash)││
│ │ - Container writes stdout/stderr → goes to Master │ │
│ │ - Container reads stdin ← comes from Master │ │
│ └──────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────┘


Container Process (e.g. /bin/bash, sh)
• Reads from stdin (/dev/tty)
• Writes to stdout/stderr (/dev/tty)

───────────────────────────────────────────────────────────────
Summary:
- PTY Master: controlled by the daemon, mediates all I/O
- PTY Slave : presented to the container process as its terminal
- Unix Socket: transports attach stream between client ↔ daemon
───────────────────────────────────────────────────────────────

Container Isolation

RustBox employs a double fork pattern for each container to ensure proper isolation:

Process Hierarchy (Per Container)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[Daemon Process]
└─> spawn_blocking()
└─> [Container Task]
└─> fork() #1
├─> [Namespaced Parent Process]
│ ├─> unshare() - Creates new namespaces
│ ├─> setup cgroups and overlay
│ └─> fork() #2
│ ├─> [Inner Child Process]
│ │ ├─> Mount /proc and /dev
│ │ ├─> chroot() to merged overlay
│ │ ├─> chdir() to working directory
│ │ └─> execv() - Execute command
│ └─> [Namespaced Parent] waits for inner child
│ └─> Unmounts /proc and /dev inside namespace
└─> [Container Task] waits for namespaced parent
├─> Unmounts overlay filesystem
├─> Cleans up cgroups
└─> Updates container state in registry

Container Lifecycle States

1
2
3
Created ──(start)──> Running ──(exit)──────> Exited

└──(stop)──> Stopped ──(exit)──> Exited

Persistent State Management

  • Container metadata: /var/lib/rustbox/containers/<container-id>.json
  • Container logs: /var/lib/rustbox/logs/<container-id>/
  • Overlay filesystems: /var/lib/rustbox/overlay/<container-id>/
  • State recovery: Daemon recovers container state on restart

Features

  • Daemon Architecture with background process and client-server communication
  • Multi-container Management supporting concurrent container execution
  • Persistent State Management with automatic recovery across daemon restarts
  • Complete Container Lifecycle (create, start, stop, remove, inspect)
  • Interactive Attach Support with TTY allocation and real-time I/O streaming
  • Real-time Logging with per-container stdout/stderr files
  • Resource Isolation using cgroups v2 (memory, CPU limits)
  • Filesystem Isolation using overlayfs with automatic cleanup
  • Full Namespace Isolation (PID, UTS, NET, USER, IPC)
  • Docker-like CLI with familiar commands (run, ps, logs, inspect, rm, attach)
  • Graceful Shutdown with proper signal handling and resource cleanup
  • Security with proper privilege separation and input validation

Requirements

  • Linux kernel 5.x or higher (with overlayfs and cgroups v2 support)
  • Rust (1.70+ recommended)
  • Root privileges (for daemon operations, mounting, and namespace creation)

Installation

Build from Source

1
2
3
git clone https://github.com/isdaniel/RustBox.git
cd RustBox
cargo build --release

Binaries

After building, you’ll have two binaries:

  • rustbox - Client CLI tool
  • daemon_rs - Background daemon process

Usage

Start the Daemon

1
2
# Start the daemon in background (requires root)
sudo ./target/release/daemon_rs 2>&1 &

The daemon will:

  • Listen on Unix socket /tmp/rustbox-daemon.sock
  • Create system directories under /var/lib/rustbox/
  • Recover existing container state from disk
  • Handle graceful shutdown on SIGTERM/SIGINT

Container Management

Create and Run Containers

1
2
3
4
5
6
7
8
# Run a container in background with TTY support (allows interactive attach)
sudo ./target/release/rustbox run --tty --memory 256M --cpu 0.5 /bin/bash

# Run a container with custom name
sudo ./target/release/rustbox run --tty --memory 256M --cpu 0.5 /bin/bash 2>&1

# Run a non-interactive container
sudo ./target/release/rustbox run --memory 256M /usr/bin/python3 script.py

Note: The --tty flag is required if you want to attach to the container later.

List Containers

1
2
3
4
5
6
7
# List running containers
sudo ./target/release/rustbox list

# List all containers (including stopped)
sudo ./target/release/rustbox list -a
# or
sudo ./target/release/rustbox list --all

Attach to Running Containers

1
2
3
4
5
# Attach to a running container (container must have been created with --tty flag)
sudo ./target/release/rustbox attach <container-id>

# Example:
sudo ./target/release/rustbox attach f1a5f84880a1

Interactive Controls:

  • Press Ctrl+P followed by Ctrl+Q to detach from container (leaves it running)
  • Press Ctrl+C to send interrupt signal and exit

Requirements:

  • Container must have been started with --tty flag
  • Container must be in Running state

Stop, Remove, and Inspect Containers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Stop a running container
sudo ./target/release/rustbox stop <container-id>

# View container logs
sudo ./target/release/rustbox logs <container-id>
sudo ./target/release/rustbox logs --tail 50 <container-id>

# Inspect container details
sudo ./target/release/rustbox inspect <container-id>

# Remove a stopped container
sudo ./target/release/rustbox remove <container-id>

# Force remove a running container
sudo ./target/release/rustbox remove --force <container-id>

Available Options:

  • --name - Custom container name (auto-generated if not provided)
  • --memory - Memory limit (e.g., “256M”, “1G”, “512000”)
  • --cpu - CPU limit as fraction of one core (e.g., “0.5”, “1.0”)
  • --workdir - Working directory inside container (default: “/“)
  • --rootfs - Path to rootfs directory (default: “./rootfs”)
  • --tty - Allocate a pseudo-TTY for interactive use (required for attach)

Directory Structure

Runtime Directories (created by daemon)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/var/lib/rustbox/
├── containers/ # Container metadata (JSON files)
│ ├── a1b2c3d4e5f6.json
│ └── f6e5d4c3b2a1.json
├── logs/ # Container logs
│ ├── a1b2c3d4e5f6/
│ │ ├── stdout.log
│ │ └── stderr.log
│ └── f6e5d4c3b2a1/
│ ├── stdout.log
│ └── stderr.log
└── overlay/ # Overlay filesystem layers
├── a1b2c3d4e5f6/
│ ├── lowerdir/ # Read-only base layer
│ ├── upperdir/ # Container changes
│ ├── workdir/ # Overlay work directory
│ └── merged/ # Final mounted filesystem
└── f6e5d4c3b2a1/
├── lowerdir/
├── upperdir/
├── workdir/
└── merged/

Source Code Structure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
src/
├── lib.rs # Public API exports
├── main.rs # Client CLI entry point
├── daemon/ # Daemon implementation
│ ├── main.rs # Daemon entry point
│ ├── server.rs # Unix socket server
│ ├── container_manager.rs # Container lifecycle management
│ └── signal_handler.rs # Graceful shutdown handling
├── ipc/ # Inter-process communication
│ ├── protocol.rs # Message types and framing
│ └── client.rs # Client-side socket communication
├── container/ # Container abstractions
│ ├── mod.rs # Container data structures
│ ├── config.rs # Configuration and validation
│ ├── sandbox.rs # Core isolation logic
│ ├── state_machine.rs # Container state transitions
│ └── id.rs # ID generation and validation
├── storage/ # Persistent storage
│ ├── metadata.rs # Container metadata management
│ └── logs.rs # Log file management
├── cli/ # CLI command implementations
│ ├── run.rs # Create and start containers
│ ├── stop.rs # Stop containers
│ ├── list.rs # List containers
│ ├── inspect.rs # Container details
│ ├── remove.rs # Remove containers
│ ├── logs.rs # View container logs
│ └── attach.rs # Attach to containers
└── error.rs # Error handling

Technical Details

IPC Protocol

Communication between client and daemon uses length-prefixed JSON messages over Unix domain sockets:

1
[4-byte length (u32, big-endian)][JSON payload]

Example:

1
0x0000001E  {"type":"ListRequest","all":true}

Container ID Format

  • 12-character hexadecimal identifiers (e.g., a1b2c3d4e5f6)
  • Auto-generated names follow adjective-noun pattern (e.g., happy-elephant)
  • CLI commands accept either ID or name

Resource Limits

  • Memory: Supports units like 100M, 1G, 512000 (bytes)
  • CPU: Fraction of one core, e.g., 0.5 for 50% CPU limit
  • Enforced via cgroups v2 at /sys/fs/cgroup/rustbox/<container-id>/

Security Model

  • Daemon runs as root for privileged operations
  • Client commands run as user, connect via Unix socket
  • Containers run in isolated namespaces (PID, NET, UTS, IPC, USER)
  • Input validation prevents directory traversal and injection attack

Final Thoughts

RustBox is not a full container system, and that’s by design — it’s transparent, hackable, and educational. Whether you’re looking to secure untrusted code, explore low-level Linux features, or just love writing systems code in Rust, RustBox is a fantastic playground.

Give it a ⭐ on GitHub and explore the source!

__此文作者__:Daniel Shih(石頭)
__此文地址__: https://isdaniel.github.io/rustbox-introduce/
__版權聲明__:本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 TW 許可協議。轉載請註明出處!

如果本文對您幫助很大,可街口支付斗內鼓勵石頭^^