Files
AetherForge/docs/E2E_VALIDATION.md
AetherForge f404a76caa
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Fix exotic CPU stub idle-mining guard and document Linux headless screenshots.
Return sane fallback CPU percent after first sample on unknown Unix platforms; add xvfb/scrot docs and stub tests; clear PROBLEMS.md open bugs.
2026-06-07 06:27:19 -07:00

346 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Secure Local Payload Validation
End-to-end validation of a forged AetherForge agent **without risking production keys or your daily driver**. This playbook recommends one primary path and tiered alternatives.
---
## Verdict: Docker Windows vs Disposable VM
| Environment | Server | Linux agent | Windows agent (full payload) |
|-------------|--------|-------------|------------------------------|
| **Host + Hyper-V VM** (recommended) | ✅ `devrun.bat` on host | ✅ optional WSL2 VM | ✅ real Win32, WMI, USB, desktop, GPU |
| **Linux Docker** | ✅ Go binary in container | ✅ partial C2 + mining | ❌ cannot compile/run Windows agent features |
| **Docker Desktop Windows containers** | ⚠️ awkward (Server Core image) | N/A | ❌ **poor fit** — see below |
### Why not Docker Windows for full payload tests?
Windows containers run on **Windows Server Core** (or similar) with a different kernel contract than desktop Windows:
- **No interactive desktop** — screenshots, clipboard, and many PowerShell UI calls fail or return empty.
- **WMI USB subscriptions, autorun.inf, LNK spread, Defender tampering** — require desktop-class Windows and often admin on a real session.
- **GPU mining (T-Rex / TeamRedMiner)** — no practical NVIDIA/AMD passthrough in Windows containers.
- **USB propagation** — container cannot see host removable drives the way a VM or bare metal can.
- **WinRM / SMB lateral spread** — needs a multi-machine lab network, not an isolated container namespace.
**Honest recommendation:** use **Docker/Linux only for server + automated CI**. For **full Windows payload validation**, use a **disposable Hyper-V (or VMware) Windows 10/11 VM** — or a dedicated second physical “burner” PC — then **revert a snapshot** when done.
---
## Tiered Test Matrix
### Tier 0 — Mining stack only (no C2, no payload)
Proves RandomX + pool worker + optional live Stratum **on the dev machine**.
```powershell
cd agent
go run ./cmd/mine-validate -seconds 20 -threads 2
```
| Validates | Does not validate |
|-----------|-------------------|
| RandomX engine, pool workers, live pool login | C2 WebSocket, forge bake, persistence, spread |
> **Note:** `mine-validate` may spam `[miner] hash error: randomx VM not initialized` during the multi-threaded pool phase while still reporting non-zero H/s and exiting 0. Treat non-zero hashrate + exit 0 as pass; investigate if exit code is 1.
### Tier 1 — Automated CI (no real agent)
```bat
test.bat
```
Or faster (skip builds + Playwright):
```powershell
.\scripts\test-suite.ps1 -SkipBuild -SkipE2E
```
| Phase | Coverage |
|-------|----------|
| Go server + agent unit/integration tests | API, forge, auth, pool, fusion |
| Vitest | Dashboard forms, preflight, offline gating |
| Playwright (`-SkipE2E` off) | Login smoke, mocked fleet UI |
Also with server already running:
```powershell
.\scripts\smoke-test.ps1 -BaseUrl http://127.0.0.1:8989
```
### Tier 2 — Server + Linux agent (same host, Linux VM, or Docker)
Good for **C2 path**, basic recon, mining install, systemd persistence — **not** Windows-only ops.
**Option A — Docker (isolated bridge, recommended for CI)**
```bash
# Automated proof (compose up + assert + teardown)
scripts/ci-docker-mining.sh # Linux / macOS / GHA
.\scripts\ci-docker-mining.ps1 # Windows + Docker Desktop
```
Or interactive:
```bash
docker compose -f docker/docker-compose.yml up --build
```
- Server on host port **18989**; dashboard `testuser` / `testpass` (see `docker/data/users.json`).
- Fleet secret `e2e-docker-fleet-secret-fixed001` in `docker/data/config.json` + `docker/agent-builtin.go`.
- Test wallet in `docker/data/config.json` and `docker/agent-builtin.go` (see E2E test address in security rules above).
- Agent container has **no internet egress** — mines via server-broadcast jobs only.
- RandomX is pure Go (`go-randomx`); agent image needs **no CGO**.
- **Assert logic:** `GET /api/v1/health``GET /api/v1/agents` (Basic auth) finds `status=online` with `hashrate_15s|1m|15m > 0`, or `GET /api/v1/dashboard/stats` shows `online_agents >= 1` and `total_hashrate > 0`. Waits up to **3 minutes**.
- GitHub Actions: `.github/workflows/ci-docker-mining.yml` on every push (`ubuntu-latest`).
- Verify manually: Fleet Roster shows `docker-e2e-linux`; hashrate fields populate after ~30s.
- Teardown: `docker compose -f docker/docker-compose.yml down --rmi local -v`
Full notes: [`docker/README.md`](../docker/README.md).
**Option B — WSL2 / Linux VM**
1. Start server on host: `devrun.bat`
2. Forge **Linux amd64** worker pointing at `http://<host-lan-ip>:8989` (VM must reach host; bind server to LAN or use Hyper-V Default Switch IP).
3. Run agent in WSL2 or a small Linux VM.
4. Crucible: `sysinfo`, `pause`/`resume`, `get_log`, `list_dir` (Linux file ops).
### Tier 3 — Full Windows payload (primary E2E path)
**Topology**
```
┌─────────────────────────────┐ ┌──────────────────────────────┐
│ Host PC (control) │ LAN │ Disposable Win10/11 VM │
│ devrun.bat → :8989 │◄───────►│ forged test agent.exe │
│ data/ logs, builds, DB │ only │ snapshot "clean" → revert │
└─────────────────────────────┘ └──────────────────────────────┘
```
**Security rules**
1. **Dedicated test data dir** — e.g. `data-e2e\` with fresh `users.json`; never copy production `data\`.
2. **Test wallet** — use the repo's recommended E2E Monero address (public test wallet, not for production):
`85JfUA9uyBZ2Kzv4ctoURyUYoYgpEu5QjQ8xSdiapFX8TpBHXkHwHQhBkxUxmoFKU85NH4dnSRBbiL8wSvcVmRqg4Wc9Trm`
Seeded automatically in `data-e2e/config.json` by `scripts/e2e-validate.ps1` and in `docker/data/config.json` for Tier 2 Docker. Do not use your production wallet.
3. **Rotate fleet secret** after tests if you ever pointed at shared `data\`.
4. **No internet egress from VM** (optional but ideal) — allow only host IP:8989 + pool Stratum if testing live shares.
5. **Snapshot before forge run** — revert VM when finished (“toss the machine”).
---
## Step-by-Step: Tier 3 Playbook
### 1. Prepare isolated server data
```powershell
$env:AETHERFORGE_E2E_USER = "testuser"
$env:AETHERFORGE_E2E_PASS = "testpass"
New-Item -ItemType Directory -Force -Path ".\data-e2e" | Out-Null
'{"testuser":"testpass"}' | Set-Content ".\data-e2e\users.json" -Encoding UTF8
```
Start server against that directory (from repo root):
```bat
bin\miner-server.exe -port 8989 -data .\data-e2e
```
Or use `devrun.bat` after pointing `-data` at `data-e2e` (or run `.\scripts\e2e-validate.ps1 -PrepareOnly`).
### 2. Calibrate for validation
In **Calibrate** (Settings):
| Setting | Test value |
|---------|------------|
| Server URL | `http://<host-ip>:8989` (must match what the VM can reach) |
| Wallet | `85JfUA9uyBZ2Kzv4ctoURyUYoYgpEu5QjQ8xSdiapFX8TpBHXkHwHQhBkxUxmoFKU85NH4dnSRBbiL8wSvcVmRqg4Wc9Trm` (or match `data-e2e/config.json`) |
| `file_logging` | **true** (required for `get_log` / `data-e2e\logs\`) |
| Stealth mode | **off** for first pass (easier debugging) |
| USB / share / auto-spread | **off** until spread is explicitly under test |
| Remote aggressive ops | **on** only in a VM snapshot you will revert |
| `agent_kill_after_days` | optional safety fuse (e.g. `1`) |
### 3. Forge a test worker
In **Forge**:
- Target OS: **Windows amd64**
- Worker name: `e2e-validate`
- Enable only features you intend to test this session
- Download `e2e-validate.exe` + paired `uninstall-e2e-validate.ps1`
Or use the orchestrator script (API forge) after server is up:
```powershell
.\scripts\e2e-validate.ps1 -ForgeAgent
```
### 4. Hyper-V VM setup (Windows)
```powershell
# Example: Hyper-V Manager or PowerShell
# 1. Create Gen2 VM, 4 GB RAM, 40 GB disk
# 2. Internal or Default Switch network (host reachable)
# 3. Take snapshot named "clean-pre-agent"
# 4. Copy forged exe into VM (shared folder or ISO)
```
**Before running the agent:** snapshot name recorded, VM has no personal data, Defender policy acceptable for your lab.
### 5. Run agent in VM
1. Execute forged exe once (install + connect).
2. Confirm agent appears on dashboard **Fleet Roster** (online).
3. Check server console for `[agent] authenticated`.
### 6. Crucible command checklist
Run against the test agent. Tick as you go.
**Core / mining**
- [ ] `sysinfo` — hostname, cores, RAM
- [ ] `pause` / `resume` / `restart` — miner control
- [ ] `connectivity_probe` — C2 + pool reachability JSON
- [ ] `get_log` — tail returns `miner.log` lines
**Recon (Windows)**
- [ ] `ps`, `netstat`, `listen_ports`
- [ ] `ipconfig`, `wifi`, `posture`, `patch_status`
- [ ] `screenshot` (needs interactive logged-in desktop)
- [ ] `camera_list` / `camera_snapshot` (needs ffmpeg + camera)
**Files (Windows)**
- [ ] `list_dir``C:\Users\<user>\`
- [ ] `read_file` — small text file
- [ ] `upload` / `download` round-trip
**Power / lifecycle**
- [ ] `exec` / `powershell` — benign echo command
- [ ] `reboot_machine` — only if snapshot revert planned
- [ ] `uninstall` or run `uninstall-*.ps1` — M-10 checklist
**Advanced (enable in forge + revert snapshot after)**
- [ ] `get_wifi_passwords`, `defender_off`, `firewall_*`
- [ ] USB spread — second USB passthrough device
- [ ] `spread_now` / LAN spread — requires second lab VM
### 7. Collect logs
| Source | Path / action |
|--------|----------------|
| Server stdout | `devrun.bat` window |
| Server agent log cache | `data-e2e\logs\<agent-id>.log` |
| Agent on disk | `%LOCALAPPDATA%\<install-dir>\miner.log` |
| Dashboard | Fleet → Remote Control → **Fetch Log** |
| API | `GET /api/v1/agents/{id}/log?refresh=1` |
```powershell
Get-ChildItem ".\data-e2e\logs\"
Get-Content ".\data-e2e\logs\<agent-id>.log" -Tail 100
```
### 8. Teardown (“toss the machine”)
1. **VM:** Hyper-V → **Revert to snapshot** `clean-pre-agent` (or delete VM).
2. **Host:** stop server; archive or delete `data-e2e\` if no longer needed.
3. **Network:** remove any temporary firewall rules allowing VM→host:8989.
4. **Secrets:** if production `data\` was ever used, rotate fleet secret in Calibrate.
---
## Quick orchestration
```powershell
# Automated tiers 01 + instructions for tier 3
.\scripts\e2e-validate.ps1
# Tier 0 only
.\scripts\e2e-validate.ps1 -SkipAutomatedTests -SkipServerCheck
# Prepare test data + print checklist (no forge)
.\scripts\e2e-validate.ps1 -PrepareOnly
```
---
## What each existing tool covers
| Tool | Tier | Scope |
|------|------|-------|
| `agent/cmd/mine-validate` | 0 | Mining only |
| `test.bat` / `scripts/test-suite.ps1` | 1 | Full automated suite |
| `scripts/smoke-test.ps1` | 1 | REST B-01B-10 |
| `scripts/ci-docker-mining.sh` / `.ps1` | 2 | Docker Linux agent hashrate proof |
| `.github/workflows/ci-docker-mining.yml` | 2 | GHA push gate |
| `server/web/e2e/*.spec.ts` | 1 | Dashboard smoke (mocked WS) |
| `docs/TEST_RESULTS.md` | 13 | Matrix IDs; M-01M-09 manual |
| `devrun.bat` | 23 | Build + launch control server |
| Forge + burner VM | 3 | Full payload |
---
## Linux vs Windows agent capabilities (validation scope)
| Feature | Windows | Linux | macOS |
|---------|---------|-------|-------|
| RandomX CPU mining + dashboard hashrate | ✅ | ✅ | ✅ |
| GPU RVN mining | ✅ | stub (detect only) | stub |
| Screenshot | ✅ (GDI+) | ✅ (scrot/import/gnome-screenshot) | ✅ (screencapture) |
| Camera | ✅ (ffmpeg) | ✅ (V4L2/ffmpeg/fswebcam) | stub |
| Clipboard | ✅ | ✅ (xclip/pbpaste) | ✅ (pbpaste) |
| File browser Crucible | ✅ | ✅ | ✅ |
| Posture / syscheck | ✅ (WMI) | ✅ (ufw/systemd/apt) | partial |
| Firewall aggressive ops | ✅ (netsh) | ✅ (ufw/iptables) | stub |
| USB / WMI spread | ✅ | ❌ | ❌ |
| SMB / WinRM spread | ✅ | ❌ | ❌ |
| SSH lateral spread | ❌ | ✅ | ✅ |
| WiFi password harvest | ✅ | stub | stub |
| Defender off | ✅ | N/A (returns error) | N/A |
| systemd / LaunchAgent persistence | — | ✅ | ✅ |
| Idle-mode mining (CPU % sample) | ✅ | ✅ (fixed: /proc/stat) | ✅ (sysctl kern.cp_time) |
| Headless Linux screenshot | N/A | ✅ with Xvfb — see below | N/A |
Use **Tier 3 Windows VM** when validating spread, GPU, screenshot, or aggressive ops. Use **Tier 2 Linux** for faster C2 regression on recon + mining.
---
## Linux headless screenshot
Docker/CI/VPS agents have no real display. `scrot`, `import`, and `gnome-screenshot` need an X server.
**Install and start a virtual framebuffer:**
```bash
apt-get install -y xvfb scrot
Xvfb :99 -screen 0 1280x720x24 &
export DISPLAY=:99
```
Then run the Crucible **Screenshot** action as usual (agent picks up `scrot` on PATH).
**One-shot custom command** (Crucible screenshot command field — no persistent `DISPLAY` in the agent process):
```bash
DISPLAY=:99 Xvfb :99 -screen 0 1280x720x24 & sleep 1; scrot -q 55 /tmp/s.jpg && base64 -w0 /tmp/s.jpg
```
On Alpine or minimal images, use the agent forge **custom screenshot command** field with the same pattern.
**Unsupported platforms** (`freebsd`, etc.) return `screenshot not supported on this platform` from `screenshot_stub.go`.
---
## References
- Automated test phases: `tests/README.md`
- Manual matrix IDs: `docs/TEST_RESULTS.md` (M-01M-10)
- Known gaps: `PROBLEMS.md`