# VPS Benchmark Node

> Applies to: ChengOS v0.2.0+ ｜ Last verified: 2026-09-25 ｜ Source: `crates/cheng-nodes/src/nodes/builtin/tools/vps_benchmark`

`tools/vps_benchmark` benchmarks a server over SSH and from the outside at once: a fixed set of
system, disk, CPU, bandwidth, and route probes runs on the host, while geolocation, ASN, open
ports, HTTP fingerprint, and reverse DNS are probed from the API host, and both halves are parsed
into one structured report. The remote script is locked at compile time — every parameter is a
boolean switch or a generated nonce — and `host`, `port`, and `credential_id` are canvas-only, so
an agent using the node as a tool can change only the test scope and the raw-output switch. Three
defaults deserve attention before you run it: host keys are accepted without a prompt unless you
turn on Strict Host Key Checking (TOFU approval), the China multi-node speedtest is off because it
downloads up to about 150 MB of metered traffic, and third-party scripts (streaming unlock,
NodeQuality) run only when you supply both a commit-pinned URL and its SHA-256.

## VPS Benchmark — `tools/vps_benchmark`

Benchmark a VPS: runs a fixed, compile-time-locked set of system/performance/network probes over SSH and combines them with external probes (geolocation, ASN, open ports, HTTP fingerprint, reverse DNS) into a structured report. The host, port, and credential are static canvas configuration and are never exposed to the LLM; as a tool, only the test scope and raw-output toggle can be set.

### Inputs

| Field | Type | Required | Default | Description |
|---|---|:-:|---|---|
| `host` | string | ✅ | — | Target VPS host (hostname or IP) |
| `port` | integer | — | `22` | SSH port used for the internal tests. Control: `number` |
| `username` | string | — | `root` | SSH login user. Overridden by the credential's `username` field when present. |
| `credential_id` | string | — | `null` | SSH credential — private key or password (resolved via CredentialRepository). Control: `credential-select` |
| `test_scope` | enum | — | `all` | Which halves of the benchmark to run. Control: `select`. Options: `all` (外部探测 + SSH 内部测试。), `external_only` (只跑本机发起的外部探测（不需要凭证）。), `internal_only` (只跑 SSH 内部测试。) |
| `include_raw` | boolean | — | `false` | Include the unparsed stdout/stderr of every stage (large; off by default). Control: `switch` |
| `enable_disk_io` | boolean | — | `true` | Run a sequential write benchmark under /var/tmp. Control: `switch` |
| `enable_bandwidth` | boolean | — | `true` | Run speedtest-cli when it is installed on the host. Control: `switch` |
| `enable_routes` | boolean | — | `true` | Run mtr against China Telecom / Unicom / Mobile backbones (requires mtr and usually root). Control: `switch` |
| `enable_cpu_benchmark` | boolean | — | `true` | Run a ~5s CPU stress test (sysbench when installed, dependency-free prime sieve otherwise). Control: `switch` |
| `enable_cn_speedtest` | boolean | — | `false` | Measure download speed from fixed China Telecom / Unicom / Mobile nodes. Downloads up to ~150 MB of metered traffic; off by default. Control: `switch` |
| `enable_ip_quality` | boolean | — | `true` | Look up IP reputation (datacenter / residential / proxy / Tor / fraud score) from public sources. Control: `switch` |
| `enable_connectivity` | boolean | — | `true` | Test outbound SMTP port reachability (25/465/587) and AI service HTTPS connectivity (ChatGPT/Claude/Gemini). Control: `switch` |
| `streaming_script_url` | string | — | `null` | Pinned (commit-locked) URL of the region-unlock script. Requires the SHA-256 below; both empty = streaming check disabled. |
| `streaming_script_sha256` | string | — | `null` | Expected SHA-256 of the script above (64 hex chars). Verified on the host before execution. |
| `enable_nq_ip_quality` | boolean | — | `false` | Run xykt/IPQuality script for IP reputation, media unlock, and mail port checks. Control: `switch` |
| `enable_nq_net_quality` | boolean | — | `false` | Run xykt/NetQuality script for network quality (BGP, NAT, delay, speedtest, iperf). Control: `switch` |
| `enable_nq_hardware` | boolean | — | `false` | Run xykt/HardwareQuality script for hardware benchmarks (CPU, GPU, memory, disk). Control: `switch` |
| `enable_nq_backroute` | boolean | — | `true` | Run xykt/NetQuality -R for backroute tracing. Control: `switch` |
| `nq_ip_quality_url` | string | — | `null` | Pinned (commit-locked) URL of the xykt/IPQuality script. Required when enable_nq_ip_quality is true. |
| `nq_ip_quality_sha256` | string | — | `null` | Expected SHA-256 of the IP quality script (64 hex chars). |
| `nq_net_quality_url` | string | — | `null` | Pinned (commit-locked) URL of the xykt/NetQuality script. Required when enable_nq_net_quality or enable_nq_backroute is true. |
| `nq_net_quality_sha256` | string | — | `null` | Expected SHA-256 of the Net quality script (64 hex chars). |
| `nq_hardware_url` | string | — | `null` | Pinned (commit-locked) URL of the xykt/HardwareQuality script. Required when enable_nq_hardware is true. |
| `nq_hardware_sha256` | string | — | `null` | Expected SHA-256 of the Hardware quality script (64 hex chars). |
| `strict_host_key_checking` | boolean | — | `false` | TOFU: prompt for host-key approval on first connect. Defaults to false for automated benchmark runs. Control: `switch` |
| `approval_timeout_secs` | integer | — | `300` | Seconds to wait for host-key approval. Control: `number` |
| `info_timeout_ms` | integer | — | `30000` | Timeout for stage 1 (system info batch). Control: `number` |
| `perf_timeout_ms` | integer | — | `420000` | Timeout for stage 2 (disk I/O + bandwidth + routes). Control: `number` |
| `streaming_timeout_ms` | integer | — | `300000` | Timeout for stage 3 (region unlock script). Control: `number` |
| `connectivity_timeout_ms` | integer | — | `60000` | Timeout for stage 4 (SMTP port + AI service connectivity). Control: `number` |
| `nodequality_timeout_ms` | integer | — | `3600000` | Timeout for stage 5 (NodeQuality comprehensive tests). Control: `number` |
| `external_timeout_ms` | integer | — | `5000` | Per-probe timeout for the external (locally originated) tests. Control: `number` |
| `total_timeout_ms` | integer | — | `5400000` | Hard deadline for the whole benchmark; partial results are still returned. Control: `number` |
| `enable_nq_fast_mode` | boolean | — | `true` | Skip lengthy Geekbench benchmarks in HardwareQuality to finish in ~1m instead of ~10m. Defaults to true. Control: `switch` |

### Outputs

| Field | Type | Description |
|---|---|---|
| `summary` | string | 给 LLM 看的一段紧凑摘要（结构化字段的自然语言压缩）。 |
| `success` | boolean | 只要有任意一个测试段成功产出结果就是 `true`。 细粒度的失败明细看 `failures`。 |
| `host` | string | Host |
| `resolved_ip` | string | 实际用于外部测试的 IP（`host` 是域名时为解析结果）。 |
| `timestamp` | string | Timestamp |
| `duration_ms` | integer | Duration Ms |
| `external` | object | External |
| `internal` | object | Internal |
| `failures` | array&lt;object&gt; | 没有产出结果的测试段及其原因。 |
| `raw_outputs` | object | Raw Outputs |
| `report_json` | string | 整个报告序列化成 JSON 字符串，方便连到 `code_python.input` 或 `chat/output` 等期望 string 类型的下游端口。 |

## Next steps

- [HTTP & Web Nodes](/docs/nodes-http-web)
- [Approvals & Human Review](/docs/exec-approvals-reviews)
- [Code Execution Nodes](/docs/nodes-code-runtime)
