Skip to content

Repository files navigation

Go Next.js Docker License

Pentest Labs

Dynamic pentesting lab platform with AI-assisted learning.

Deploy isolated, dockerized lab environments on demand. Practice pentesting, solve CTF challenges, simulate bug bounties — all with an integrated AI coach that guides without giving away the answers.


Features

  • Dynamic Zones — Spin up isolated lab environments from templates. Each zone gets its own Docker network, resource limits, and TTL enforcement.
  • Template System — Import labs from ZIP files containing lab.yml configuration. Share templates with the community.
  • AI Assistant — Multi-provider AI coaching (OpenAI, Anthropic, Ollama) with hint, explain, and debrief modes. Flag-leak prevention built in.
  • Terminal in Browser — Full interactive terminal via xterm.js + WebSocket, connected directly to lab containers.
  • Objectives & Scoring — Flag submission, progressive hints, leaderboards, and multiple scoring methods (sum, weighted, time-decay).
  • Multi-Mode Labs — Pentest, CTF, Bug Bounty, and custom lab types on one platform.
  • Team Support — Organizations with role-based access (owner, admin, member).
  • Admin Panel — Template approval, zone management, AI usage monitoring, audit logging.
  • Setup Wizard — First-run wizard handles database migration, admin account creation, and platform configuration.

Architecture

┌─────────────────────────────────────────────────────────┐
│                  Frontend (Next.js)                       │
│   Dashboard │ Zone Detail │ Terminal │ AI Chat │ Admin    │
├─────────────────────────────────────────────────────────┤
│                  API Gateway (Traefik)                    │
│         Rate Limiting │ Security Headers │ Routing        │
├─────────────────────────────────────────────────────────┤
│                  Control Plane (Go)                       │
│   Auth │ Templates │ Zone Lifecycle │ Scoring │ AI        │
├─────────────────────────────────────────────────────────┤
│                  Runtime Plane                            │
│   ComposeDriver (Docker) │ K8sDriver (Kubernetes)        │
├─────────────────────────────────────────────────────────┤
│                  AI Plane (LiteLLM)                       │
│   OpenAI │ Anthropic │ Ollama │ Fallback Chains           │
├─────────────────────────────────────────────────────────┤
│                  Data Layer                               │
│   PostgreSQL │ Redis │ Object Storage                     │
└─────────────────────────────────────────────────────────┘

Quick Start

Prerequisites

  • Docker Engine 24.0+
  • Docker Compose v2
  • At least one AI provider API key (OpenAI recommended)

1. Clone & Configure

git clone https://github.com/tegal1337/pentest-labs.git
cd pentest-labs
cp .env.example .env

Edit .env with your API keys:

JWT_SECRET=your-secure-random-string-here
OPENAI_API_KEY=sk-...

2. Start Services

docker compose up -d

This starts: PostgreSQL, Redis, Traefik, LiteLLM, API backend, Worker, and Frontend.

3. Run Setup Wizard

Open http://localhost in your browser. The setup wizard will:

  1. Verify all services are healthy
  2. Create your admin account
  3. Configure platform settings

4. Import Lab Templates

Templates are in the templates/ directory. Import via the web UI or API:

cd templates/01-juice-shop
zip -r juice-shop.zip lab.yml
curl -X POST http://localhost/api/v1/templates/import \
  -H "Authorization: Bearer <token>" \
  -F "file=@juice-shop.zip"

5. Accessing zone labs from your browser

Public labs are reachable through Traefik on ports 80 (and 443 if TLS is configured), not through random Docker-published host ports. Each running zone gets a hostname ingress_domain (default pattern: {first-8-of-zone-uuid}.labs.local).

URL format: http://<ingress_domain>/

DNS / hosts

  • Same machine as Docker Desktop / Linux daemon: Often 127.0.0.1 <ingress_domain> in your hosts file is enough because Traefik publishes 80:80.
  • Another device on your LAN: Use the LAN IP of the Docker host instead of loopback (e.g. 192.168.1.10 <ingress_domain> on the laptop you browse from).
  • Wildcard DNS (optional): Point *.labs.local at the Traefik host with an internal resolver (e.g. dnsmasq) so you don’t add a hosts line per zone.

The zone detail screen in the app shows Open lab and the raw hostname as a reminder. If the hostname does not resolve, the browser cannot reach Traefik with the correct Host header and routing to that zone will fail.


Tech Stack

Component Technology Purpose
Backend Go 1.25 API server, zone orchestration
Frontend Next.js 16 + TypeScript Dashboard, terminal, AI chat
Database PostgreSQL 16 Persistent data
Cache Redis 7 Events, job queue, sessions
AI Gateway LiteLLM Multi-provider routing, rate limits
Reverse Proxy Traefik v3 Rate limiting, routing, TLS
Runtime Docker Compose Zone container orchestration
Terminal xterm.js + WebSocket Browser-based shell

Project Structure

pentest-labs/
├── backend/                    # Go API server
│   ├── cmd/api/                # API entrypoint
│   ├── cmd/worker/             # Background worker
│   ├── internal/
│   │   ├── ai/                 # LiteLLM gateway client
│   │   ├── config/             # Environment configuration
│   │   ├── events/             # Redis pub/sub event broker
│   │   ├── handler/            # HTTP handlers
│   │   ├── middleware/         # Auth, logging middleware
│   │   ├── migrate/            # Embedded SQL migrations
│   │   ├── model/              # Domain models
│   │   ├── recording/          # Lab session recording
│   │   ├── repository/         # Database access layer
│   │   ├── runtime/            # Container runtime drivers
│   │   │   ├── compose/        # Docker Compose driver
│   │   │   └── kubernetes/     # Kubernetes driver
│   │   ├── scheduler/          # Multi-worker job scheduler
│   │   ├── scoring/            # Scoring plugin system
│   │   ├── server/             # HTTP server + routes
│   │   ├── service/            # Business logic
│   │   ├── team/               # Team/org management
│   │   ├── terminal/           # WebSocket terminal handler
│   │   ├── vpn/                # WireGuard VPN manager
│   │   └── worker/             # TTL enforcement
│   ├── pkg/validator/          # Lab config validation
│   ├── migrations/             # SQL migration files
│   ├── Dockerfile
│   └── Makefile
├── frontend/                   # Next.js application
│   ├── src/
│   │   ├── app/                # Pages (App Router)
│   │   ├── components/         # React components
│   │   ├── hooks/              # Custom hooks
│   │   ├── lib/                # API client, utilities
│   │   ├── stores/             # Zustand state stores
│   │   └── types/              # TypeScript interfaces
│   └── Dockerfile
├── litellm/                    # LiteLLM proxy configuration
│   └── config.yaml
├── traefik/                    # Traefik gateway configuration
│   ├── traefik.yml
│   └── dynamic/
├── templates/                  # Lab template library
│   ├── 01-juice-shop/
│   ├── 02-dvwa/
│   └── ...
├── docs/
│   └── PRD.md                  # Product Requirements Document
├── docker-compose.yml
└── .env.example

API Reference

Authentication

Method Endpoint Description
POST /api/v1/auth/register Register new user
POST /api/v1/auth/login Login, returns JWT tokens
POST /api/v1/auth/refresh Refresh access token
POST /api/v1/auth/logout Invalidate session
GET /api/v1/auth/me Get current user

Templates

Method Endpoint Description
POST /api/v1/templates/import Upload ZIP template
GET /api/v1/templates List templates
GET /api/v1/templates/:id Get template details
POST /api/v1/templates/:id/validate Dry-run validation
POST /api/v1/templates/:id/publish Make public
GET /api/v1/templates/:id/versions Version history
DELETE /api/v1/templates/:id Delete template

Zones

Method Endpoint Description
POST /api/v1/zones Create zone from template
GET /api/v1/zones List user's zones
GET /api/v1/zones/:id Get zone details
POST /api/v1/zones/:id/start Start zone
POST /api/v1/zones/:id/stop Stop zone
POST /api/v1/zones/:id/reset Reset to initial state
DELETE /api/v1/zones/:id Destroy zone
GET /api/v1/zones/:id/status Runtime status
GET /api/v1/zones/:id/services Service list + health
GET /api/v1/zones/:id/events SSE event stream
GET /api/v1/zones/:id/terminal WebSocket terminal
GET /api/v1/zones/:id/objectives Objectives + progress
POST /api/v1/zones/:id/flags/submit Submit flag
GET /api/v1/zones/:id/score Current score

AI Assistant

Method Endpoint Description
POST /api/v1/zones/:id/ai/chat General chat
POST /api/v1/zones/:id/ai/hint Get contextual hint
POST /api/v1/zones/:id/ai/explain Explain vulnerability
POST /api/v1/zones/:id/ai/debrief Session debrief
GET /api/v1/ai/providers List AI providers
GET /api/v1/ai/models List available models

Leaderboards

Method Endpoint Description
GET /api/v1/leaderboards/global Global leaderboard
GET /api/v1/leaderboards/:templateId Per-lab leaderboard

Admin

Method Endpoint Description
GET /api/v1/admin/stats Platform statistics
GET /api/v1/admin/zones All zones (all users)
GET /api/v1/admin/workers Worker status
GET /api/v1/admin/ai/usage AI usage stats
GET /api/v1/admin/audit Audit log
POST /api/v1/admin/templates/:id/approve Approve template

Lab Template Format

Templates are ZIP files containing a lab.yml configuration:

version: 1

metadata:
  name: "My Lab"
  type: "pentest"        # pentest | ctf | bug-bounty | custom
  difficulty: "medium"   # easy | medium | hard | insane
  tags: ["web", "sqli"]

services:
  - name: "app"
    image: "vulnerable/app:latest"
    ports:
      - container_port: 8080

objectives:
  mode: "flags"
  flags:
    - id: "flag-1"
      title: "Find the vulnerability"
      value: "HLAB{my_flag_here}"
      points: 100

ai:
  enabled: true
  profile: "coach-basic"

See docs/PRD.md section 3.2 for the complete schema reference.


Included Lab Templates

# Name Type Difficulty Vulnerabilities
1 OWASP Juice Shop Pentest Easy OWASP Top 10
2 DVWA Pentest Easy SQLi, XSS, Command Injection
3 WebGoat Pentest Medium JWT, XXE, Deserialization
4 crAPI Pentest Medium OWASP API Top 10
5 DVGA Pentest Medium GraphQL Security
6 SQL Injection CTF CTF Medium UNION, Blind, Time-based
7 XSS Challenge CTF Easy Reflected, Stored, DOM
8 Broken Auth Pentest Medium JWT, Session Fixation
9 SSRF Lab Pentest Hard SSRF, Filter Bypass
10 Linux Privesc Pentest Hard SUID, Sudo, Cron

Development

Backend

cd backend
cp .env.example .env
# Edit .env with your values

make run          # Run API server
make run-worker   # Run background worker
make test         # Run tests
make lint         # Run linter
make build        # Build binaries

Frontend

cd frontend
npm install
npm run dev       # Development server on :3000
npm run build     # Production build

Database Migrations

Migrations run automatically on API startup. To run manually:

make migrate-up
make migrate-down

Deployment

Single VPS (Recommended for start)

Minimum requirements: 4 CPU cores, 8 GB RAM, 100 GB SSD

# Clone and configure
git clone https://github.com/tegal1337/pentest-labs.git
cd pentest-labs
cp .env.example .env
# Edit .env

# Start everything
docker compose up -d

# Check health
curl http://localhost/health

Scaling Path

  1. Single VPS → All services on one machine
  2. Multi-Worker → Add worker nodes, scheduler distributes zones
  3. Kubernetes → Swap ComposeDriver for K8sDriver (same API, same templates)

Security

  • Zone Isolation — Each zone runs in its own Docker network with no inter-zone communication
  • Container Hardening — No privileged containers, all capabilities dropped, seccomp profiles
  • Resource Limits — CPU, memory, PID, and disk limits per container
  • Egress Control — Internet access denied by default
  • AI Safety — Flag-leak prevention, output filtering, rate limiting
  • API Security — JWT auth, rate limiting via Traefik, input validation

See SECURITY.md for vulnerability reporting.


License

This project is licensed under the MIT License. See LICENSE for details.


Contributing

We welcome contributions! See CONTRIBUTING.md for guidelines.


Acknowledgments

  • OWASP for vulnerable application projects
  • LiteLLM for multi-provider AI routing
  • Traefik for the reverse proxy
  • xterm.js for the browser terminal

About

Dynamic pentesting lab platform with AI-assisted learning.

Resources

Contributing

Security policy

Stars

16 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors