initial commit
Some checks failed
CI / Go — node-agent tests (push) Has been cancelled
CI / Go — edge-gateway build (push) Has been cancelled
CI / Node — lint, typecheck, test, build (push) Has been cancelled

This commit is contained in:
smueller
2026-06-26 10:45:08 +02:00
commit e37ea87b35
118 changed files with 7726 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
# HexaHost GameCloud — Implementation Status
Last updated: 2026-06-26
## Current phase: Phase 0 — Repository and foundations
### Completed
| Area | Status | Notes |
|------|--------|-------|
| Monorepo layout | Done | pnpm workspace, Turborepo |
| Go node-agent | Done | Config, protocol types, health, agent loop stub |
| Go edge-gateway | Stub | Disabled by default; Phase 8 |
| Docker Compose dev stack | Done | PostgreSQL, Redis, MinIO, Mailpit, API, Worker, Web |
| Environment template | Done | `.env.example` |
| CI pipeline | Done | Lint, typecheck, tests, Go tests, build |
| Documentation skeleton | Done | ADR, architecture, threat model, installation |
| WHMCS integration layout | Placeholder | Directory structure and README |
| Deploy placeholders | Done | Traefik, Ansible, systemd, Prometheus |
### In progress / next (Phase 1)
- User registration, login, sessions
- Email verification and password reset
- TOTP 2FA
- Admin bootstrap CLI
- Prisma schema and migrations
### Abnahmekriterium Phase 0
- [x] Repository structure and configuration baseline
- [x] Local infrastructure compose file
- [x] Node agent builds and tests pass
- [x] CI workflow defined
- [ ] All services start locally end-to-end (requires `docker compose up` validation)
- [ ] Full API/Web/Worker feature implementation (Phase 1+)
### Known limitations
- Edge gateway is intentionally not implemented (Join-to-Start is Phase 8).
- API, Worker, and Web are minimal health-check stubs in Phase 0.
- Traefik, Ansible, and production compose are documented but not fully implemented.
- Node agent does not yet connect to the control plane WebSocket.
### Test commands
```bash
pnpm install
pnpm lint
pnpm typecheck
pnpm test
cd apps/node-agent && make test
```

View File

@@ -0,0 +1,70 @@
# ADR 0001: Monorepo architecture
- **Status:** Accepted
- **Date:** 2026-06-26
- **Deciders:** HexaHost GameCloud core team
## Context
HexaHost GameCloud is a multi-component platform: web UI, REST API, background workers, per-node Go agents, and a future edge gateway. Teams need shared contracts, consistent tooling, and atomic changes across services.
## Decision
Adopt a **pnpm + Turborepo monorepo** with the following application split:
| Component | Technology | Responsibility |
|-----------|------------|----------------|
| `apps/web` | Next.js (App Router) | User and admin UI |
| `apps/api` | NestJS + Fastify | REST API, auth, orchestration |
| `apps/worker` | NestJS / Node | BullMQ jobs, scheduler |
| `apps/node-agent` | Go | Game node daemon, container lifecycle |
| `apps/edge-gateway` | Go | TCP/UDP Join-to-Start (Phase 8) |
| `packages/*` | TypeScript | Shared database, contracts, UI, config |
Supporting infrastructure:
- **PostgreSQL** — primary data store (Prisma ORM)
- **Redis** — cache, locks, BullMQ queues
- **S3-compatible storage** — backups and large artifacts
- **Docker Compose** — local and control-plane production deployment
- **systemd** — node agent on game nodes
- **Traefik** — TLS termination and routing (external)
## Rationale
1. **pnpm workspaces** provide fast, disk-efficient dependency sharing across TypeScript packages.
2. **Turborepo** caches build and test tasks with explicit dependency graphs.
3. **NestJS + Fastify** offers structured modules, validation, and OpenAPI for the API layer.
4. **Next.js** supports SSR/RSC, i18n, and a modern React UX without a proprietary UI kit.
5. **Go** for node-agent and edge-gateway: small static binaries, strong concurrency, suitable for systemd daemons on game nodes.
6. **Prisma** gives type-safe schema evolution and migration tooling shared by API and worker.
## Consequences
### Positive
- Single repository for cross-cutting changes (API contract + UI + worker).
- Shared TypeScript types via `packages/contracts`.
- Unified CI for all languages.
- Clear deployment boundaries: Compose for control plane, systemd for agents.
### Negative
- Larger clone size and CI surface area.
- Go modules live outside the Node dependency graph; versioning is manual.
- Developers need Node 22, pnpm, Go 1.23, and Docker.
## Alternatives considered
| Alternative | Rejected because |
|-------------|------------------|
| Polyrepo | Harder to keep contracts and releases in sync |
| Kubernetes | Explicitly out of MVP scope; Compose + VMs first |
| Single language (all TypeScript) | Go better fits low-level node agent requirements |
| tRPC only (no REST) | REST + OpenAPI required for WHMCS integration and public API docs |
## Related documents
- `docs/architecture/overview.md`
- `docs/operations/installation.md`
- `docs/security/threat-model.md`

View File

@@ -0,0 +1,100 @@
# Architecture overview
HexaHost GameCloud is a self-hosted, multi-tenant platform for on-demand Minecraft servers.
## High-level diagram
```mermaid
flowchart TB
subgraph users [Users]
Browser[Web Browser]
MC[Minecraft Client]
end
subgraph control [Control Plane]
Web[Next.js Web]
API[NestJS API]
Worker[BullMQ Worker]
PG[(PostgreSQL)]
Redis[(Redis)]
S3[(S3 / MinIO)]
end
subgraph nodes [Game Nodes]
Agent[Go Node Agent]
Docker[Docker Engine]
Server[Minecraft Containers]
end
subgraph future [Phase 8+]
Edge[Edge Gateway]
end
Browser --> Web
Web --> API
API --> PG
API --> Redis
Worker --> Redis
Worker --> PG
Worker --> S3
API <-->|mTLS WebSocket| Agent
Agent --> Docker
Docker --> Server
MC --> Server
MC -.-> Edge
Edge -.-> API
```
## Component responsibilities
### Control plane
Runs on one or more VMs (Ubuntu 24.04 / Debian 13). Handles authentication, server metadata, scheduling decisions, billing projection, and job orchestration. **Never** mounts the Docker socket.
### Game nodes
Dedicated Linux VMs with Docker Engine (cgroup v2). Each node runs the **node-agent** as a systemd service. The agent connects **outbound** to the API via mTLS WebSocket and executes signed lifecycle commands locally.
### Data flow
1. User creates a server via the web UI.
2. API persists state in PostgreSQL and enqueues provisioning jobs.
3. Worker selects a node, reserves resources, and sends `server.provision` to the agent.
4. Agent creates an isolated container and reports `server.state` transitions.
5. Backups stream to S3; metadata stays in PostgreSQL.
### Security boundaries
| Boundary | Mechanism |
|----------|-----------|
| User → API | HTTPS, session cookies, CSRF, rate limits |
| API → Agent | mTLS, node token, signed JSON messages |
| Agent → Docker | Local Unix socket only, no remote exposure |
| Game container → Internet | Egress rules, no internal network access by default |
## Repository layout
See [ADR 0001](../adr/0001-monorepo-architecture.md) for the full monorepo structure.
## Protocol
Agent communication uses versioned JSON envelopes over WebSocket. Message types include `agent.hello`, `agent.heartbeat`, `server.start`, and `server.state`. See `apps/node-agent/internal/protocol/messages.go`.
## Deployment models
| Environment | Mechanism |
|-------------|-----------|
| Local development | `deploy/compose/compose.dev.yml` |
| Production control plane | Docker Compose + Traefik |
| Game nodes | Ansible + systemd node-agent |
## Phase roadmap
| Phase | Focus |
|-------|-------|
| 0 | Repository, infra, CI, docs |
| 1 | Authentication |
| 2 | Single-node vertical slice |
| 37 | Panel features, multi-node, idle shutdown |
| 8 | DNS, edge gateway, join-to-start |
| 9 | Billing, production hardening |

View File

@@ -0,0 +1,112 @@
# Local development installation
This guide covers setting up HexaHost GameCloud on a single machine for development.
## Prerequisites
| Tool | Version |
|------|---------|
| Node.js | 22.x |
| pnpm | 9.x |
| Go | 1.23+ |
| Docker Engine | 24+ |
| Docker Compose | v2 |
Optional:
- `make` (for node-agent)
- Traefik with external network `traefik-network`
## 1. Clone and configure
```bash
git clone <repository-url> hexahost-gamecloud
cd hexahost-gamecloud
cp .env.example .env
```
Edit `.env` and set at minimum:
- `SESSION_SECRET` and `ENCRYPTION_KEY` — generate with `openssl rand -base64 32`
- `DATABASE_URL`, `REDIS_URL` — defaults work with compose
- `NODE_ID` — any unique string for local agent testing
## 2. Install dependencies
```bash
pnpm install
```
## 3. Start infrastructure
```bash
# Optional: create Traefik network if using external routing
docker network create traefik-network 2>/dev/null || true
# Start PostgreSQL, Redis, MinIO, Mailpit, API, Worker, Web
docker compose -f deploy/compose/compose.dev.yml --env-file .env up -d
```
Verify health:
```bash
curl -s http://localhost:3001/healthz
curl -s http://localhost:3000/api/health
```
Mailpit UI: http://localhost:8025
MinIO console: http://localhost:9001 (default `minioadmin` / `minioadmin`)
## 4. Run applications locally (without Docker)
Alternatively, run only infrastructure in Docker and apps on the host:
```bash
docker compose -f deploy/compose/compose.dev.yml --env-file .env up -d postgres redis minio mailpit
pnpm dev
```
## 5. Node agent (optional)
```bash
cd apps/node-agent
export NODE_ID=local-dev-node
export NODE_AGENT_PUBLIC_URL=ws://localhost:3001/api/v1/nodes/ws
make build
make run
```
Health: http://localhost:9100/healthz
## 6. Quality checks
```bash
pnpm lint
pnpm typecheck
pnpm test
cd apps/node-agent && make test
```
## Troubleshooting
### `traefik-network` not found
Either create the network (`docker network create traefik-network`) or remove the external network from compose for pure local dev.
### Port conflicts
Adjust `API_PORT`, `WEB_PORT`, `POSTGRES_PORT`, `REDIS_PORT` in `.env`.
### MinIO bucket missing
The `minio-init` service creates the bucket on first start. Restart compose if it failed:
```bash
docker compose -f deploy/compose/compose.dev.yml up minio-init
```
## Next steps
- Phase 1: database migrations and authentication — see `docs/IMPLEMENTATION_STATUS.md`
- Production deployment: `deploy/traefik/`, `deploy/ansible/` (Phase 9)

View File

@@ -0,0 +1,59 @@
# Threat model (initial)
**Status:** Draft — Phase 0
**Last updated:** 2026-06-26
**Scope:** HexaHost GameCloud control plane, workers, node agents, and game containers.
## Assets
- User credentials and sessions
- Node enrollment tokens and mTLS certificates
- Game server world data and backups
- Billing and audit records
- Internal service credentials (database, Redis, S3)
## Trust boundaries
1. Public internet → Web/API (untrusted)
2. API ↔ Node Agent (mutually authenticated)
3. Node Agent → Docker (trusted local host)
4. Game container → network (untrusted, tenant-controlled code)
## Threat catalog
| ID | Threat | Description | Mitigation (planned / partial) | Residual risk |
|----|--------|-------------|-------------------------------|---------------|
| T01 | Malicious registered user | Abuse file upload, API, or quotas | AuthZ on every endpoint, path validation, rate limits, quotas | Medium — requires ongoing abuse monitoring |
| T02 | Compromised mod/plugin file | Malicious JAR in server directory | Server-side install only, checksum validation, optional ClamAV | Medium |
| T03 | Compromised user account | Attacker uses stolen session | 2FA, session revocation, login rate limits, audit log | LowMedium |
| T04 | Compromised node agent | Attacker controls agent process | mTLS, signed commands, no inbound agent port, cert rotation | Medium |
| T05 | Compromised game container | Escape or lateral movement | Non-privileged containers, dropped caps, seccomp, network isolation | Medium |
| T06 | Stolen agent token | Replay enrollment or impersonate node | One-time enrollment, token rotation, mTLS binding | Low |
| T07 | Replay of lifecycle message | Duplicate start/stop commands | Idempotency keys, generation counters, message IDs | Low |
| T08 | Path traversal | Access files outside server directory | Server-side path normalization, deny `..` and symlinks | Low |
| T09 | ZIP bomb | Decompression DoS via upload | Size, file count, compression ratio limits | Low |
| T10 | Symlink attack | Escape via symlink in archive | Reject symlinks on extract by default | Low |
| T11 | SSRF via resource pack URL | Server fetches internal URLs | URL allowlist, block RFC1918, validate schemes | Medium |
| T12 | Internal port scan from game server | Scan control plane from container | Egress firewall, no host network mode | LowMedium |
| T13 | Secret exfiltration via logs | Tokens in console or API logs | Structured logging with redaction, no secrets in env dumps | Low |
| T14 | Queue flooding | Enqueue excessive jobs | Per-user rate limits, queue depth alerts | Medium |
| T15 | Start spam | Repeated start requests (join-to-start) | Rate limits, idempotent starts, captcha at edge (Phase 8) | Medium (Phase 8) |
| T16 | Backup manipulation | Tamper with or replace backups | SHA-256 checksums, server-side encryption, immutable S3 policies | Low |
| T17 | Supply-chain attack | Compromised npm/go dependency | Lockfiles, CI audit, SBOM, image scanning | Medium |
| T18 | Manipulated runtime image | Unauthorized Docker image | Digest-pinned images, admin-managed catalog only | Low |
| T19 | DNS takeover | Hijack game subdomain | DNS provider auth, monitoring, short TTL only where needed | Low |
| T20 | WebSocket hijacking | Steal or inject agent channel | mTLS, origin checks, correlation IDs | Low |
| T21 | Tenant isolation failure | User A accesses User B server | Server-side authZ, row-level checks, audit | Critical — must test continuously |
## Out of scope (documented dependencies)
- DDoS mitigation at network edge (external infrastructure)
- Physical host compromise
- Mojang/Microsoft account security
## Next steps
- [ ] STRIDE review per component (Phase 1)
- [ ] Container seccomp/AppArmor profiles (Phase 2)
- [ ] Penetration test before production (Phase 9)
- [ ] `docs/security/container-isolation.md`, `secrets.md`, `data-retention.md`