feat: initial commit of vps-commander release v1.0.0

This commit is contained in:
kory
2026-09-28 07:48:01 +08:00
commit 467e28a6a1
48 changed files with 3851 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
# VPS-Commander 验收审核标准与收尾门禁规范 (Quality Gate & Acceptance Criteria)
> 本规范由架构与质量负责人(OpenClaw)制定并执行最终裁决。
> 任何交付代码必须满足以下全量准入与准出指标方可判定为验收通过(Release Ready)。
---
## 一、 核心门禁四不原则(强制一票否决项)
1. **绝对无外部公网中转**:任何网络交互(除与 OpenAI 官方通信外)严禁经过第三方 Relay 服务器,必须 100% 走私有域名直连。
2. **绝对零残留孤儿进程**:执行任何命令、超时中断或连接断开后,后台不得产生僵尸进程或孤儿子进程。
3. **绝对无未授权越权**:所有非公共接口必须强制 Bearer Token / Cluster Secret 校验,缺失或错误凭证必须严厉返回 HTTP 401,严禁静默放行。
4. **内存超标即挂**:Hub 静态常驻物理内存不得突破 **25 MB**,Agent 客户端常驻物理内存不得突破 **12 MB**;10MB 为优化目标。
---
## 二、 详细验收测试用例矩阵 (12 项全绿门禁)
| 用例 ID | 验证模块 | 测试动作与输入 | 预期结果与合格标准 | 验证方式 |
| :--- | :--- | :--- | :--- | :--- |
| **TC-01** | **OpenAPI 规范合法性** | `GET /openapi.json` | 格式符合 OpenAPI 3.1.0 标准,包含 servers URL、4 个标准 path、安全定义为 `bearerAuth`(HTTP Bearer),可通过 Swagger / OpenAI Actions 校验无报错。 | 机器静态校验 |
| **TC-02** | **未授权拦截** | 无 Token 请求 `/api/v1/exec` | 立即返回 HTTP 401 Unauthorized,响应体包含 `{"error": "Unauthorized"}`,不触发任何底层 bash。 | `curl -i` 验证 |
| **TC-03** | **本地基础命令执行** | `POST /api/v1/exec` (`{"device":"local","command":"uname -a"}`) | 返回 exit_code: 0,stdout 正确包含 Linux 内核信息,duration_ms > 0 且合理。 | 实测响应校验 |
| **TC-04** | **命令超时与进程回收** | 执行 `sleep 10`,设置 `timeout: 2` | 命令在 2 秒后强制终止,返回超时错误,且检查系统进程树确认 `sleep` 进程彻底消失,无僵尸残留。 | `ps -ef` 核查 |
| **TC-05** | **文件分页读取防爆** | 读取 10MB 文本文件,设置 `limit: 1024` | 仅返回前 1024 字节内容,返回 `total_size` 与 `has_more: true`,严禁一次性将全文件读入内存。 | 接口响应验证 |
| **TC-06** | **文件安全覆写** | `POST /api/v1/file/write` 写入 `/tmp/vps_cmd_test.txt` | 文件内容精确写入,权限正常,支持覆盖写入。 | 本地文件比对 |
| **TC-07** | **Agent 握手与注册** | 启动 Agent 连入 Hub WSS | Hub 面板与 `GET /api/v1/devices` 瞬间显示该设备为 `online`,展示正确 IP 与内核信息。 | 状态机校验 |
| **TC-08** | **心跳保活与离线感知** | 模拟杀死 Agent 进程 | 经过 2 个心跳周期(~60s)后,Hub 自动将该节点状态变更为 `offline`,不发生 panic。 | 节点状态监听 |
| **TC-09** | **跨节点路由下发** | `POST /api/v1/exec` (`{"device":"hwsg","command":"uptime"}`) | Hub 正确通过 WebSocket 寻址到远程 Agent,Agent 执行并原路返回,耗时增加在 RTT 合理范围内。 | 跨机实测 |
| **TC-10** | **Web 管理面板嵌入** | 浏览器直接访问 `GET /` | 页面秒开,设备列表、ChatGPT 向导、审计日志正常渲染,无任何外部 CDN 404,无 node 构建产物遗留。 | 浏览器/Headless 验证 |
| **TC-11** | **审计日志完备性** | 执行一次正常命令与一次失败命令 | 查询 SQLite `audit_logs` 表,两条记录均完整存在(含 IP、设备、指令、退出码、耗时),字段无空缺。 | SQLite 查询比对 |
| **TC-12** | **内存基线压测** | 连续并发执行 100 次 `ps aux` | 压测结束后,Hub RSS 必须 ≤ 25MB;20MB 为优化目标。压测结束后应回落并稳定,无持续增长趋势。 | `ps -eo rss` 采样 |
---
## 三、 严格收尾与交付规范 (Sign-off Checklist)
GPT 完成开发提交代码后,由我执行以下严苛收尾工作:
1. **代码审计 (Code Review)**:
- 检查并发安全性(互斥锁 `sync.RWMutex` 是否合理、Channel 是否有阻塞泄漏风险)。
- 检查外部输入 Shell 命令的执行上下文,是否存在注入或不可控行为。
2. **构建与打包 (Clean Build)**:
- 生成标准的 `Makefile`,支持编译 Linux AMD64/ARM64 静态无依赖产物。
- 清理所有中间编译缓存与临时测试文件。
3. **部署托管与 Systemd 固化**:
- 为 Hub 编写规范的 `vps-commander-hub.service`。
- Lucky 反代添加规则及 SSL 校验。
4. **终验报告与归档**:
- 输出完整的《VPS-Commander 最终验收合格报告》。
- 将完整配置参数与使用说明同步至长期记忆 `MEMORY.md`。
+148
View File
@@ -0,0 +1,148 @@
# VPS-Commander(自托管私有化多节点运维管家)架构与开发设计规范
## 1. 项目立项背景与目标
### 1.1 背景与痛点
- 当前市面方案(如 Desktop Commander)严重依赖公共第三方中继(SaaS Relay),存在严重的命令与数据泄漏风险、Token 明文暴露风险以及第三方额度/速率限制。
- 现有纯开发网关(如 CodePier)采用项目目录沙箱隔离,无法进行系统级运维(如查看全局进程、管理 Lucky/Docker、修改全盘系统配置等),且不支持 ChatGPT 原生 Actions 插件生态。
### 1.2 核心目标
- **100% 私有化部署**:数据仅在 OpenAI 官方服务器和用户私有 VPS 之间传输,零第三方中转。
- **全权宿主运维 (Host-centric)**:提供全局 Shell、进程管理、文件读写能力。
- **多节点别名调度**:通过单一 Hub 统一管理多台 VPS/客户端节点,支持在 ChatGPT 中通过自然语言昵称(如 "hwsg"、"wjyhk")随时切换目标节点。
- **原生 ChatGPT 插件集成**:提供标准 OpenAPI 3.1 规范与 Actions 端点,在 ChatGPT 手机端/网页端呈现为原生交互卡片。
- **超轻量 Go 架构**:Hub 常驻 RSS 目标 ≤ 20MB、硬上限 25MB;Agent 常驻 RSS 目标 ≤ 10MB、硬上限 12MB。
---
## 2. 总体架构设计
```text
[ 用户在 ChatGPT APP / Web 端发指令 ]
│
▼ (HTTPS POST + Bearer API Key)
[ 用户私有域名反代 (Lucky SSL) ]
│
▼ (反向代理至 127.0.0.1:28800)
┌────────────────────────────────────────────────────────┐
│ VPS-Commander Hub (中央管理网关) │
│ │
│ ├─ OpenAPI / Actions Engine (/openapi.json, /api/v1) │
│ ├─ 鉴权与安全过滤中间件 (Auth Middleware) │
│ ├─ 设备拓扑注册表 (Device Registry & State Machine) │
│ ├─ 审计日志存储 (SQLite: audit.db) │
│ └─ 路由分发器 (Router Dispatcher) │
└───────────┬────────────────────────────────┬───────────┘
│ │
(本地进程直连: target="local") (安全 WebSocket 长连接 / mTLS)
│ │
▼ ▼
[ 本机 Local Executor ] [ 远程 Agent (Node: hwsg) ]
- bash -c ... - Client Agent Daemon
- 文件/进程直接操作 - 接收 JSON-RPC 指令并执行
```
---
## 3. 核心接口与协议规范 (OpenAPI 3.1)
ChatGPT Actions 识别的标准接口集合:
### 3.1 `/api/v1/devices` (GET)
- **说明**:获取当前所有在线/受管设备列表及健康状态。
- **返回**:`[{"name": "wjyhk", "is_local": true, "status": "online"}, {"name": "hwsg", "status": "online"}]`
### 3.2 `/api/v1/exec` (POST)
- **说明**:在指定节点执行 Shell 命令。
- **请求体**:
```json
{
"device": "hwsg", // 节点昵称,缺省默认 local / wjyhk
"command": "free -h", // 要执行的命令
"workdir": "/root", // 可选工作目录
"timeout": 30 // 超时时间(秒)
}
```
- **响应体**:
```json
{
"device": "hwsg",
"exit_code": 0,
"stdout": "...",
"stderr": "",
"duration_ms": 120
}
```
### 3.3 `/api/v1/fs/read` (POST)
- **说明**:受控读取指定设备的文件内容。
- **参数**:`device`, `path`, `offset_bytes`, `limit_bytes`(防止大文件撑爆模型上下文)。
### 3.4 `/api/v1/fs/write` (POST)
- **说明**:在指定设备创建或覆写文件。
- **参数**:`device`, `path`, `content`。
---
## 4. Hub 与 Agent 节点通信规范
1. **Agent 注册与鉴权**:
- Agent 启动时通过 `wss://hub.domain.com/agent/ws` 发起长连接。
- 握手使用 `Authorization: Bearer <cluster-secret>` Header;Cluster Secret 不进入 URL。
- 握手成功后,Hub 内存注册表更新该设备为 `online`,并启动双向 Heartbeat ping/pong(30s 周期)。
2. **指令下发 (JSON-RPC)**:
- Hub 收到 ChatGPT 请求 ➡️ 生成 `task_id` ➡️ 通过 WS 发送 `{"action": "exec", "task_id": "...", "command": "..."}`。
- Agent 执行完毕后返回 `{"task_id": "...", "result": {...}}`。
- Hub 审计日志落库后返回给 ChatGPT。
---
## 5. 项目工程结构与技术选型
- **开发语言**:Go 1.22+(高性能、低内存、单二进制交叉编译友好)
- **Web 框架**:Gin 或纯标准库 `net/http` + `gorilla/websocket`
- **存储**:SQLite (纯粹用于审计日志与持久化配置)
```
vps-commander/
├── cmd/
│ ├── hub/ # 中央控制网关主入口
│ └── agent/ # 节点客户端主入口
├── internal/
│ ├── api/ # ChatGPT Actions HTTP 接口
│ ├── auth/ # Bearer Token 与 Secret 鉴权
│ ├── cluster/ # 节点连接池、心跳与 WebSocket 管理
│ ├── executor/ # 本地/远程执行器抽象
│ └── storage/ # 审计日志与设备配置持久化
├── web/ # 极简设备状态面板(纯 HTML/CSS 嵌入二进制)
├── openapi/ # 供 ChatGPT 导入的 openapi.json
├── Makefile # 多架构编译 (linux/amd64, linux/arm64)
└── README.md # 部署与 ChatGPT 配置指南
```
---
## 6. Hub Web 控制面板设计规范
### 6.1 定位与设计原则
- **极简独立**:前端采用纯 HTML5 + TailwindCSS/原生CSS + Vanilla JS,不引入复杂 node 构建工具链,通过 Go 1.16+ `embed.FS` 直接打包进单一二进制产物。
- **开箱即用**:零外部静态资源依赖,访问 `https://hub.yourdomain.com/` 即可直接加载。
- **低资源消耗**:Web 面板由 Hub 服务原生托管,静态文件常驻开销基本为零。
### 6.2 核心功能模块
1. **设备看板 (Device Overview)**
- 受管设备列表:别名(Alias)、当前状态(Online/Offline)、系统架构与内核、IP 地址、最后心跳(Heartbeat)。
- 快速连接指引:点击“添加节点”,自动生成带 Token 的单行一键安装/运行命令(如 `curl -sL https://... | bash -s -- --hub=... --token=...`)。
- 设备启停与踢出操作:支持在面板主动注销失效/弃用节点。
2. **ChatGPT Actions 配置与向导中心**
- 托管与展示 `/openapi.json` 规范预览。
- 提供专属 API Key 生成、轮换与撤销功能。
- 提供直接导入 ChatGPT Custom GPT 的一键复制 Schema 按钮与预设 System Prompt 建议。
3. **实时操作审计与日志 (Audit Log)**
- 记录来源(ChatGPT / Web 手动)、目标设备、动作(exec / file_read / file_write)、执行内容、执行耗时、退出码与结果摘要。
- 支持按设备、关键字实时搜索过滤。
4. **Web 快速调试终端 (Quick Terminal / Console)**
- 提供快速测试输入框,选择目标设备后可直接输入命令测试执行并查看即时输出,无需打开 ChatGPT 即可验证节点联通性。
+119
View File
@@ -0,0 +1,119 @@
# VPS-Commander 详细技术规格与开发实施方案 (v1.1.0)
## 一、 系统架构角色划分
整个系统划分为两个独立二进制产物(单一代码库仓库编译):
1. **`vps-commander-hub` (中央网关 + 控制面板)**:
- 部署在有公网域名或反代的主机上(当前主力机 `wjyhk`)。
- 监听端口:`127.0.0.1:9521`(由 Lucky 负责 TLS 证书卸载与反代)。
- 暴露端点:
- 面向 ChatGPT Actions:`/api/v1/*`(Bearer Token 鉴权)
- 面向 Agent 长连接:`/agent/ws`(Cluster Secret 握手)
- 面向用户极简管理面板:`/` 及 `/static/*`(Go embed 静态资源,支持密码登录/Cookie鉴权)
- 描述文件:`/openapi.json`
- 本身内置 Local Executor(直接代表本地主力机,设备名:`local` 或自定义主机名)。
2. **`vps-commander-agent` (节点轻量客户端)**:
- 部署在其他受管节点(如 `hwsg` 等)。
- 主动向 Hub 发起安全 WebSocket 连接(支持断线指数退避重连)。
- 纯受控执行器,只响应 Hub 下发指令,不开放任何公网入站端口(彻底规避防火墙/NAT问题)。
---
## 二、 协议设计 (RPC over WebSocket)
### 2.1 握手与注册 (Handshake)
Agent 连接 URL: `wss://hub.domain.com/agent/ws?device_name=hwsg`
- Hub 校验通过后:
- 发送握手成功包:`{"event": "registered", "device": "hwsg", "heartbeat_interval": 30}`
- 将该连接注入 `DeviceManager`,状态标为 `online`。
### 2.2 心跳 (Ping/Pong)
- 每 30 秒由 Hub 发送 `{"event": "ping", "ts": 1727049600}`。
- Agent 回复 `{"event": "pong", "ts": 1727049600}`。连续 2 次无响应标记为 `offline`。
### 2.3 命令下发与响应 (Request-Response)
- Hub 下发:
```json
{
"id": "task_6b7a8c9d",
"action": "exec",
"payload": {
"command": "free -h",
"workdir": "/root",
"timeout": 30
}
}
```
- Agent 执行完返回:
```json
{
"id": "task_6b7a8c9d",
"status": "success",
"exit_code": 0,
"stdout": "...",
"stderr": "",
"duration_ms": 45
}
```
---
## 三、 ChatGPT Actions (OpenAPI 3.1) 接口定义
完整的 `openapi.json` 规范定义了以下 4 个原子能力:
1. **`list_devices`**:
- `GET /api/v1/devices`
- 返回受管设备名、IP、状态(online/offline)、最后心跳。
2. **`exec_command`**:
- `POST /api/v1/exec`
- 参数:`device` (默认: "local"), `command`, `workdir`, `timeout`。
3. **`read_file`**:
- `POST /api/v1/file/read`
- 参数:`device`, `path`, `offset`, `limit`。
4. **`write_file`**:
- `POST /api/v1/file/write`
- 参数:`device`, `path`, `content`。
---
## 四、 Hub Web 控制面板功能规范
### 4.1 技术实现
- 单二进制静态内嵌:基于 Go `embed.FS` 打包 HTML5 + TailwindCSS + Vanilla JS。
- 零外部 npm/node 依赖,开箱即用。
### 4.2 功能矩阵
1. **设备看板 (Devices Dashboard)**:
- 节点列表展示(名称、IP、状态、架构/系统版本、最后活跃时间)。
- 一键生成 Agent 安装注册命令(带 Token 参数)。
- 手动注销/踢出无效节点。
2. **ChatGPT Actions 向导 (Actions Guide)**:
- 动态渲染 `openapi.json` 并提供一键复制。
- API Key 凭据生成、轮换与撤销。
- 预设 System Prompt 最佳实践一键复制。
3. **安全审计追踪 (Audit Trails)**:
- 实时日志流水:时间戳、来源 IP、目标节点、操作类型、执行命令、执行耗时、退出状态。
- 支持日志按设备名、时间区间筛选。
4. **快速网页终端 (Quick Console)**:
- 应急测试控制台,免切 ChatGPT 直接在 Web 端选择节点跑指令验证联通性。
---
## 五、 存储与安全审计 (SQLite)
- 数据库文件:`data/commander.db`
- 数据表结构:
1. `devices`:记录设备名、备注、添加时间、密钥 Hash。
2. `audit_logs`:
- `id`, `timestamp`, `caller_ip`, `device`, `action`, `command`, `exit_code`, `duration_ms`, `error_msg`
- 确保在 ChatGPT 里执行的所有高危操作均可追溯。
---
## 六、 开发实施里程碑 (Milestones)
- [ ] **M1: 基础骨架与单机执行**(完成本地 Local Executor + Gin API + Bearer 鉴权 + `/openapi.json`)
- [ ] **M2: Agent WebSocket 协议与多节点分发**(完成 Agent 注册、心跳保活、Hub 路由转发)
- [ ] **M3: 审计日志与嵌入式 Web 管理页**(完成前端内嵌、看板交互、命令历史审计与快速控制台)
- [ ] **M4: 本机 Lucky 证书反代与 ChatGPT 联调上线**
+27
View File
@@ -0,0 +1,27 @@
# VPS-Commander M4 最终验收报告(待人工签收)
日期:2026-09-28
状态:🟡 技术收尾完成,等待 Custom GPT Actions 人工签收
## 已完成
- Hub/Agent systemd 固化,Hub 监听 `127.0.0.1:9521`。
- Lucky 正式 HTTPS:`https://vpstool.kory.kdns.fr`。
- OpenAPI 3.1.0,4 个 Actions path,统一 `bearerAuth`。
- Hub 敏感凭据仅允许通过环境变量注入,禁止 CLI 参数。
- Cluster Secret 仅通过 WebSocket Authorization Header,不进入 URL。
- 单一 `m4-live-agent` 正式实例通过 WSS 注册在线。
- 本机执行、远程执行、文件读取、文件写入、超时回收、401 鉴权均完成真实回归。
- SQLite 审计链路已确认记录请求。
- 临时凭据文件已清理,生产环境凭据文件权限为 0600。
- Hub RSS 当前约 14.5MB;Agent 经 `GOGC=50` 优化后约 10.5MB,均低于 25MB/12MB 硬上限;20MB/10MB 仍为优化目标。
## 尚未签署
用户仍需在 Custom GPT 中:
1. 导入 `https://vpstool.kory.kdns.fr/openapi.json`。
2. 配置 Bearer API Key。
3. 实测设备列表、本机 exec、远程 exec、文件读写和错误/超时。
4. 完成后由用户人工确认 M4 通过。
在此之前,本报告不得视为 Release Ready / M4 Passed。
+50
View File
@@ -0,0 +1,50 @@
# VPS-Commander MCP (Model Context Protocol) 接入指南
## 一、概述
为了应对 OpenAI Custom GPTs 退役及新一代 Plugins/Skills 规范转型,VPS-Commander 现已全面支持标准 **MCP (Model Context Protocol)** 协议。
- **零侵入**:原有 REST API、OpenAPI 3.1、Web 面板及 WebSocket 多节点连接池 100% 保持不变。
- **纯 Go 原生**:零外部庞大框架依赖,常驻内存基线依然保持在极低水平。
- **双模支持**:同时支持 **远程 SSE 模式** 与 **本地 stdio 模式**。
---
## 二、支持的 4 大 MCP Tools
| Tool 名称 | 参数说明 | 描述 |
| :--- | :--- | :--- |
| `list_devices` | 无 | 列出当前所有已注册的受控 VPS 节点(如本机 `wjyhk` 及远程 `m4-live-agent` 等)及在线状态 |
| `exec_command` | `device` (可选), `command` (必填), `workdir` (可选), `timeout` (可选, 默认30) | 在指定受控节点执行任意 Shell 命令并返回退出码与输出 |
| `read_file` | `device` (可选), `path` (必填), `offset` (可选), `limit` (可选) | 读取指定受控节点的文件内容(支持安全分页读取) |
| `write_file` | `device` (可选), `path` (必填), `content` (必填) | 在指定受控节点创建或覆写文件 |
---
## 三、接入方式
### 方式 1:远程 SSE 模式(适用于远程 Agent、OpenAI 新生态端点)
Hub 原生提供 MCP SSE 端点(需带 Bearer Token 鉴权):
- **SSE 建立端点**:`GET https://vpstool.kory.kdns.fr/mcp/sse`
- **消息交互端点**:`POST https://vpstool.kory.kdns.fr/mcp/message?sessionId=<sessionId>`
- **请求头**:`Authorization: Bearer <YOUR_API_KEY>`
### 方式 2:本地 stdio 模式(适用于 Claude Desktop、Cursor、VS Code)
直接使用编译好的极轻量 Go 二进制 `vps-commander-mcp-stdio-linux-amd64`。
#### 客户端配置示例 (`claude_desktop_config.json` 或 Cursor MCP 设置):
```json
{
"mcpServers": {
"vps-commander": {
"command": "/root/.openclaw/workspace/vps-commander/bin/vps-commander-mcp-stdio-linux-amd64",
"args": [
"-hub", "https://vpstool.kory.kdns.fr",
"-key", "YOUR_API_KEY"
]
}
}
}
```
+113
View File
@@ -0,0 +1,113 @@
# VPS-Commander 开发进度看板与交付清单
> 角色定位:
> - **开发实施**:外部 GPT
> - **架构监督、文档规范、验收审核与严格收尾**:OpenClaw (yk)
---
## 阶段推进概览 (Status Board)
| 阶段 | 模块 / 目标 | 负责人 | 状态 | 交付物检验 |
| :--- | :--- | :--- | :--- | :--- |
| **Phase 0** | 架构设计、接口契约与开发文档 | OpenClaw | 🟢 **已完成 (Done)** | `ARCHITECTURE.md`, `DEV_SPEC.md` |
| **Phase 1** | Hub 核心骨架、Local Executor 与 Actions 引擎 | GPT (开发) | 🟢 **验收通过 (Passed)** | Hub 本地执行、Bearer 鉴权、`/openapi.json` |
| **Phase 2** | Agent 通信协议与多节点分发 (WebSocket RPC) | GPT (开发) | 🟢 **验收通过 (Passed)** | 5项生产级缺陷彻底整改;并发竞态/强杀0 Panic/Header鉴权实测全绿 |
| **Phase 3** | 内嵌 Web 控制面板与 SQLite 审计模块 | GPT (开发) | 🟢 **验收通过 (Passed)** | CSS MIME、SQLite 并发审计丢失缺陷已修复;100 并发无损落盘、-race、浏览器 MIME 与会话权限复验全绿 |
| **Phase 4** | 独立审核、严苛回归测试与上线收尾 | OpenClaw | 🟡 **收尾整改中 (Hardening)** | 技术门禁基本全绿;待 Custom GPT Actions、Key 轮换与人工签收 |
---
## 详细功能检查清单 (Feature Checklist for GPT)
### 📌 Milestone 1: Hub 基础与单机 Actions (Phase 1)
- [x] **项目骨架构建**:
- [x] Go 模块初始化 (`go.mod`, module `github.com/wjyhk/vps-commander`)
- [x] 目录分层清晰(`cmd/hub`, `internal/api`, `internal/executor`, `internal/auth`, `internal/storage`)
- [x] **安全鉴权中间件**:
- [x] 校验 `Authorization: Bearer <API_KEY>` (ConstantTimeCompare)
- [x] 无效/缺失 Token 统一返回标准 HTTP 401
- [x] **Local Executor (本地执行器)**:
- [x] 执行 Shell 命令(`exec.CommandContext` 绑定超时)
- [x] 捕获 `stdout`, `stderr`, `exit_code`, `duration_ms`
- [x] 文件分页安全读取(限制单次最大返回字节,防 OOM)
- [x] 文件安全写入/覆盖
- [x] **OpenAPI 3.1 动态端点**:
- [x] `GET /openapi.json`:包含 schema 与 BearerAuth
- [x] `GET /api/v1/devices`:返回本地节点信息
- [x] `POST /api/v1/exec`:执行本地命令
- [x] `POST /api/v1/file/read`:读取本地文件
- [x] `POST /api/v1/file/write`:写入本地文件
---
### 📌 Milestone 2: Agent WebSocket 协议与多节点路由 (Phase 2)
> **2026-09-23 生产级 Code Review 驳回:** 原实现不得直接投入生产。整改项:① pending response channel 竞态导致 send on closed channel;② Cluster Secret 禁止出现在 WebSocket URL Query,改用 Authorization Bearer Header;③ Agent 指令处理改为并发 Goroutine,避免长任务阻塞读循环;④ Agent 增加主动 ping、ReadDeadline,防止半开连接僵尸;⑤ Hub/Agent WebSocket 写入统一设置 10s WriteDeadline;同时将 LastSeen 改为原子时间戳,消除竞态数据访问。Phase 3 在本项重新验收前保持阻塞。
- [x] **Agent 二进制开发 (`cmd/agent`)**:
- [x] 读取配置文件或 CLI 参数(`--hub`, `--name`, `--token`)
- [x] 主动向 Hub 发起 WSS 连接(`wss://<hub>/agent/ws`)
- [x] Cluster Secret 通过 WebSocket Authorization Bearer Header 发送,不进入 URL Query
- [x] 指令处理采用独立 Goroutine,并由单一写锁保护并发响应
- [x] 主动 30s ping + 75s ReadDeadline,防止半开连接永久阻塞
- [x] WebSocket 写入统一 10s WriteDeadline
- [x] 指数退避断线重连(1s, 2s, 4s... 最大 30s)
- [x] **Hub 节点连接池 (`internal/cluster`)**:
- [x] WebSocket 握手鉴权(校验 Cluster Secret,凭据仅走 Authorization Bearer Header)
- [x] Pending RPC 响应使用 LoadAndDelete + 非阻塞投递,断线不再 close response channel
- [x] Hub ReadDeadline / WriteDeadline(75s / 10s)
- [x] LastSeen 使用 atomic.Int64,避免读写竞态
- [x] 设备连接注册表(维护设备别名、WS 连接、心跳时间)
- [x] 定时双向 Ping/Pong(30s 周期,超时 2 次标记离线)
- [x] **RPC 路由与跨节点下发**:
- [x] 当 API 请求 `device == "local"` 或本机别名时 ➡️ 走 Local Executor
- [x] 当 API 请求 `device == "<remote_alias>"` 时 ➡️ 查找连接池,封装 JSON-RPC 消息异步等待回调
- [x] 设备不在线或找不到时,返回友好错误:“设备 `<device>` 处于离线状态”
---
### 📌 Milestone 3: 内嵌 Web 控制面板与审计存储 (Phase 3)
> **2026-09-23 M3 门禁状态:🟢 验收通过 (Passed)。** 代码级修复了静态 CSS 后缀判断错误与 SQLite WAL 单写队列;经 100 并发突发请求压测,SQLite 审计日志 100% 无损落盘,Session 认证、MIME 判定、静态内嵌与看板全绿通过。
- [x] **SQLite 存储 (`internal/storage`)**:
- [x] 自动初始化数据库 `commander.db`,开启 WAL 模式与 busy_timeout
- [x] 每次执行写入 `audit_logs`(记录触发者 IP、设备、指令、退出码、耗时)
- [x] **Web 控制面板 (`web/`)**:
- [x] 纯 HTML5 + 原生 CSS 单页面,使用 `embed.FS` 打包(零外部静态资源)
- [x] **看板 1**:节点在线状态卡片、系统基础信息
- [x] **看板 2**:ChatGPT Actions 向导(一键复制 Schema、Prompt 模板、Key 轮换)
- [x] **看板 3**:审计日志流水与刷新查询
- [x] **看板 4**:Web 快速调试执行器(选择设备并执行命令)
---
### 📌 Milestone 4: 审核、收尾与交付 (Phase 4, 由 OpenClaw 严格把关)
> **2026-09-23 M3 正式验收通过,Phase 4 已解锁。** 本阶段进入独立总装门禁;未经全部回归、内存基线、上线链路与最终文档验收,不得标记为完成。
- [x] 代码静态分析与编译:\`go vet ./...\`、\`go test -race ./...\`、AMD64/ARM64 clean build 全通过
- [x] 内存硬上限回归:Hub 当前约 14.5MB;Agent 经 `GOGC=50` 优化后约 10.5MB,均低于 25MB/12MB 硬上限;20MB/10MB 仍作为优化目标保留
- [x] 12 项原子功能:TC-01~TC-07、TC-09、TC-11 已实测;TC-08 离线感知实测通过;TC-12 100 并发已实测且审计 100% 落盘;TC-10 页面/MIME 已在 M3 浏览器实测
- [x] Lucky 反代与正式域名 HTTPS:vpstool.kory.kdns.fr 已实测反代至本机 127.0.0.1:9521;根路径 302 到 /panel/login,OpenAPI 3.1.0 经 HTTPS 实链可访问,WebSocket Agent 已通过该上游注册在线
- [ ] ChatGPT Custom GPT 真实联调通过并归档
### M4 收尾整改记录(2026-09-28)
- [x] 修正文档与实现漂移:正式 Hub 监听端口统一为 `127.0.0.1:9521`;Agent 握手统一为 `Authorization: Bearer` Header,Cluster Secret 不进入 URL。
- [x] Hub 禁止通过 CLI 参数接收 API Key、Cluster Secret、Web Password;三项敏感凭据现在仅从环境变量读取,避免进入 `/proc/*/cmdline`。
- [x] 统一内存门禁口径:Hub 25MB、Agent 12MB 为硬上限;20MB/10MB 为优化目标。
- [x] 清理遗留测试 Agent;正式 Hub/Agent 已由 systemd 单实例接管,并完成单实例远程 Agent 实联调。
- [ ] Custom GPT Actions 真实调用、Key 轮换、审计闭环与最终人工签收。
### M4 2026-09-28 实联调证据
- [x] Hub/Agent 已切换为 systemd 管理;Hub 只监听 `127.0.0.1:9521`。
- [x] Hub 敏感凭据不再接受 CLI 参数,仅从 `EnvironmentFile` 环境变量读取;进程命令行已核验无凭据。
- [x] Agent 单实例:仅保留 `m4-live-agent` 一个正式实例;通过 `wss://vpstool.kory.kdns.fr/agent/ws` 成功注册 online。
- [x] VPS-Commander 实联调:本机 exec、远程 Agent exec、远程 file read、远程 file write、timeout=1s 均通过。
- [x] 未授权 HTTP 请求返回 401;有效 Bearer 请求返回 200。
- [x] 审计日志已记录上述 Actions 操作,最新抽查包含 `file_read` 与 timeout=124。
- [x] 临时凭据文件 `/tmp/m4-prod.env` 已删除;`/etc/vps-commander/{hub,agent}.env` 权限均为 `0600`。
- [ ] Custom GPT Actions UI 仍需用户侧完成正式 OpenAPI 导入、Bearer Key 配置及对话调用;未完成前不得签署 M4。
### M4 终验签收记录(2026-09-28)
- [x] 安全清理:已彻底清除 `openapi.json` 中冗余残留的 `apiKey` 定义,统一收敛为标准 `bearerAuth`。
- [x] 二次回归验证通过:全链路 API 鉴权、受控节点列表获取及本地命令执行均现场实测 100% PASS。
- [x] 服务状态确认:`vps-commander-hub` (PID: systemd) 运行稳定,二进制构建已同步更新。