Files
lan-manager/docs/requirements.md

386 lines
20 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.
# 局域网机器管理后台 — 需求文档
## 一、项目概述
搭建一个本地局域网机器管理后台,用于集中管理多台虚拟机/主机20 台以内),直观展示机器信息、服务部署情况及机器之间的转发/依赖关系,解决"机器多、IP 多、服务分散、容易遗忘"的痛点。
系统分为**访客模式**和**管理员模式**
- **访客**无需登录可查看机器的在线状态、已同步的系统数据CPU/内存/磁盘等)、服务列表,但无法查看 IP 地址、MAC 地址、拓扑关系,也无法执行任何管理操作。
- **管理员**:登录后可查看完整信息(含 IP、MAC、拓扑关系执行增删改、SSH 信息获取、导入导出等所有操作。
---
## 二、核心功能模块
### 1. 用户认证
- **管理员账号**:预设一组用户名/密码,通过环境变量或配置文件初始化
- **认证方式**Session/Cookie 或简单 Token
- **未登录用户**:自动降级为访客模式,仅开放只读脱敏接口
### 2. 机器管理(增删改查)
| 字段 | 说明 | 是否必填 | 访客可见 |
|------|------|---------|---------|
| 主机名/别名 | 用户自定义的易记名称,如 `web-server-01` | 是 | ✅ 是 |
| IP 地址 | 机器在局域网中的固定 IP`192.168.1.100` | 是 | ❌ 否(仅管理员) |
| MAC 地址 | 可选,用于辅助识别 | 否 | ❌ 否(仅管理员) |
| 操作系统 | Linux / Windows / macOS可下拉选择 + 自定义) | 是 | ✅ 是 |
| 系统版本 | 如 `Ubuntu 22.04``Windows 11``macOS 14` | 否 | ✅ 是 |
| 备注/描述 | 自由文本,记录用途、负责人等信息 | 否 | ❌ 否(仅管理员) |
| 状态 | 在线 / 离线(自动检测) | 自动 | ✅ 是 |
| SSH 系统信息 | CPU / 内存 / 磁盘 / 运行时间等(手动触发获取,可同步到机器记录) | 按需 | ✅ 是(已同步的数据) |
| 创建时间 / 更新时间 | 系统自动记录 | 自动 | ❌ 否(仅管理员) |
### 3. 服务管理
- 每台机器可以关联**多个服务条目**
- 服务字段:
- **服务名称**(如 `nginx``frps``docker``mysql``redis` 等)
- **端口号**(如 `80``443``8080`
- **协议**TCP / UDP / HTTP / HTTPS
- **备注**(自由描述,如 "反向代理到 192.168.1.50:8080"
- 服务类型支持**预设常用服务** + **自定义服务**
- **访客可见性**:访客可以看到服务名称、端口、协议,但**不可查看备注**(备注可能包含敏感 IP 或内部信息)
### 4. 机器关系管理
- 机器之间可以建立**连接关系**,用于表达端口转发、代理、依赖等
- 关系字段:
- **源机器** → **目标机器**
- **关系类型**(预设 + 自定义):
- `端口转发`(如 Nginx 反代、FRP 穿透)
- `依赖`(如 A 机器上的应用依赖 B 机器的数据库)
- `主从`(如主从复制、集群节点)
- `自定义`
- **端口信息**:源端口 → 目标端口(如 `8080 → 80`
- **备注**:自由描述
- 关系应支持**双向可视化**A→B 建立关系后,两边都能看到)
- **访客可见性**:❌ **完全不可见**,拓扑图和关系列表仅对管理员开放
### 5. 在线状态检测
- 定时对每台机器执行 **ICMP Ping** 检测
- 检测间隔:**1 分钟**
- 界面用颜色/图标直观展示在线状态:🟢 在线 / 🔴 离线
- **访客可见性**:✅ **可见**
### 6. SSH 系统信息获取(安全敏感)
- **不保存任何 SSH 凭据**(用户名、密码、密钥均不持久化)
- 仅支持 **密码认证**,不支持密钥认证
- **仅管理员可见和操作**:在机器详情页提供单独的按钮 **"获取系统信息"**
- 点击后弹窗要求输入 SSH **用户名**和**密码**
- 连接成功后获取以下信息并展示:
- 主机名、操作系统版本(精确)
- CPU 使用率 / 核心数
内存使用率 / 总量
- 磁盘使用率 / 各分区
- 运行时间uptime
- 监听中的端口列表
- **单次有效**:凭据仅在本次请求中使用,用完即销毁,不写入任何存储
- 获取到的信息可选择性地**同步到机器记录中**如系统版本、CPU、内存、磁盘同步后访客即可查看这些已缓存的数据
- SSH 连接超时时间10 秒
### 7. 拓扑/关系图可视化
- 以**节点-连线图**的形式展示所有机器及其关系
- 节点颜色区分操作系统类型
- 连线标注关系类型和端口号
- 支持拖拽、缩放、点击节点查看详情
- 使用 G6 或类似的图可视化库
- **访客可见性**:❌ **完全不可见**,仅管理员可访问拓扑图页面
### 8. 数据导入/导出
- 支持 **JSON 格式**完整导出(机器 + 服务 + 关系)
- 支持 **JSON 格式**导入(覆盖或追加模式)
- 导出文件名带时间戳,如 `lan-manager-backup-20260414.json`
- **管理员专属功能**,访客无权限
### 9. 操作日志
- 记录所有增删改操作:
- 操作时间
- 操作类型(创建 / 修改 / 删除)
- 操作对象(机器 / 服务 / 关系)
- 变更内容(旧值 → 新值)
- 来源 IP请求的 IP
- 操作用户(管理员用户名)
- 日志只增不改,可在独立页面查看
- 支持按时间/操作类型筛选
- **管理员专属功能**
---
## 三、UI 界面设计
### 页面 1机器列表主页访客/管理员共用)
```
┌─────────────────────────────────────────────────────────────────┐
│ 🔍 搜索 IP / 主机名 [Linux▼] │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────┐ ┌─────────────┐ ┌───────────┐ ┌──────────┐ ┌────────┐ │
│ │状态 │ │ 主机名 │ │ IP* │ │ 系统 │ │ 服务数 │ │
│ ├─────┤ ├─────────────┤ ├───────────┤ ├──────────┤ ├────────┤ │
│ │ 🟢 │ │ nginx-proxy │ 192.168.*.* │ Linux │ 2 │ │
│ │ 🟢 │ │ db-master │ 192.168.*.* │ Linux │ 1 │ │
│ │ 🔴 │ │ dev-win │ 192.168.*.* │ Windows │ 3 │ │
│ │ 🟢 │ │ mac-build │ 192.168.*.* │ macOS │ 0 │ │
│ └─────┘ └─────────────┘ └───────────┘ └──────────┘ └────────┘ │
│ │
│ 底部导航: [机器列表] [拓扑图*] [操作日志*] [导入/导出*] [登录] │
└─────────────────────────────────────────────────────────────────┘
```
> 注:带 `*` 的功能/数据仅管理员可见,访客访问时隐藏或显示为占位符(如 IP 显示为 `***`)。
- 支持按系统类型筛选、按 IP / 主机名搜索访客搜索时只能匹配主机名IP 对访客不可见)
- 点击某行进入**机器详情**
### 页面 2机器详情访客/管理员共用,但字段可见性不同)
```
┌──────────────────────────────────────────────────────────────┐
│ ← 返回 nginx-proxy │
├──────────────────────────────────────────────────────────────┤
│ 基本信息 [编辑*] │
│ IP: 192.168.1.1 (访客显示: ***.***.*.*) │
│ MAC: AA:BB:CC:DD:EE:FF (访客不可见) │
│ 系统: Linux (Ubuntu 22.04) │
│ 状态: 🟢 在线 │
│ 备注: 主网关入口 (访客不可见) │
│ │
│ SSH 系统信息(管理员触发后展示) │
│ CPU: 12% (4 cores) │
│ 内存: 2.1G / 8G (26%) │
│ 磁盘: / 45G / 100G (45%), /data 120G / 500G (24%) │
│ 运行时间: 15 days, 3:22 │
│ 监听端口: 22, 80, 443 │
│ [获取系统信息*] [同步到记录*] │
│ │
│ 服务列表 [+ 添加服务*] │
│ ┌─────────┬──────┬──────┬──────────────────────┐ │
│ │ 名称 │ 端口 │ 协议 │ 备注* │ │
│ ├─────────┼──────┼──────┼──────────────────────┤ │
│ │ nginx │ 80 │ TCP │ 反代入口 │ │
│ │ nginx │ 443 │ TCP │ HTTPS │ │
│ └─────────┴──────┴──────┴──────────────────────┘ │
│ │
│ 关联关系 [+ 添加关系*] │
│ → db-master :80 → :3306 [端口转发] [编辑*] [删除*] │
│ → frps :8080 → :8080 [依赖] [编辑*] [删除*] │
└──────────────────────────────────────────────────────────────┘
```
> 注:带 `*` 的按钮/字段仅对管理员显示;关联关系区域对访客完全隐藏。
### 页面 3拓扑图
- 力导向图force-directed graph节点可拖拽
- 节点颜色Linux 蓝色、Windows 绿色、macOS 紫色
- 连线样式:
- 端口转发:实线 + 端口标注
- 依赖:虚线 + 文字标注
- 主从:带箭头实线
- 点击节点高亮关联连线,其余淡化
- **仅管理员可访问**,访客访问时重定向到机器列表或提示登录
### 页面 4操作日志
```
┌──────────────────────────────────────────────────────────────────┐
│ [全部▼] [2026-04-14] [导出日志*] │
├──────────────────────────────────────────────────────────────────┤
│ 2026-04-14 15:30:22 admin 修改 机器 nginx-proxy │
│ 备注: "" → "主网关入口" │
│ 2026-04-14 15:28:01 admin 创建 服务 nginx on nginx-proxy │
│ 2026-04-14 14:55:10 admin 删除 关系 db-master → cache-01 │
│ 2026-04-14 14:30:00 admin 创建 机器 cache-01 │
└──────────────────────────────────────────────────────────────────┘
```
- **仅管理员可访问**
---
## 四、技术选型
| 层 | 技术 | 说明 |
|---|---|---|
| 后端 | **Go 1.21+** | 单二进制部署,内置 net/http 或 Gin 框架SSH 客户端用 golang.org/x/crypto/ssh |
| 前端 | **Vue 3 + Vite** | 轻量,配合 Element Plus / Naive UI 组件库 |
| 拓扑图 | **AntV G6** | 专门的图可视化库,力导向图 + 自定义节点样式 |
| 存储 | **SQLite** | 单文件数据库,适合 20 台以内数据量 |
| 在线检测 | Go `net` 包 ICMP Ping / 系统 ping 命令回退 | 定时 goroutine1 分钟间隔 |
| SSH | `golang.org/x/crypto/ssh` | 纯 Go 实现,不依赖系统 ssh 命令,仅密码认证 |
| 认证 | Session/Cookie | 简单用户名密码,预设单管理员账号 |
### 项目结构
```
lan-manager/
├── server/
│ ├── main.go # 入口HTTP 服务启动
│ ├── config/ # 配置管理
│ ├── db/ # SQLite 数据库连接 + migration
│ ├── models/ # 数据模型 (Machine, Service, Relationship, Log, User)
│ ├── handlers/ # HTTP 请求处理
│ ├── services/ # 业务逻辑 (ping, ssh, import/export, auth)
│ └── middleware/ # CORS, 认证中间件, 日志中间件
├── web/
│ ├── src/
│ │ ├── views/ # 页面组件 (MachineList, MachineDetail, Topology, Logs, Login)
│ │ ├── components/ # 复用组件 (StatusBadge, ServiceTable, RelationEditor)
│ │ ├── api/ # 前端 API 封装
│ │ └── App.vue
│ └── index.html
├── scripts/
│ └── lan-manager.service # Systemd 服务示例
├── go.mod
├── go.sum
├── Makefile # 构建脚本
└── README.md
```
---
## 五、数据存储设计
```sql
machines :
id INTEGER PRIMARY KEY AUTOINCREMENT
hostname TEXT NOT NULL -- 主机名/别名
ip TEXT NOT NULL UNIQUE -- IP 地址
mac TEXT -- MAC 地址
os_type TEXT NOT NULL -- Linux / Windows / macOS / Other
os_version TEXT -- 系统版本
notes TEXT -- 备注
is_online INTEGER DEFAULT 0 -- 0=离线, 1=在线
last_ping_at DATETIME -- 最后一次 ping 时间
-- SSH 系统信息字段(管理员获取后可选择同步到这里,供访客查看)
cpu_info TEXT -- CPU 信息 JSON
memory_info TEXT -- 内存信息 JSON
disk_info TEXT -- 磁盘信息 JSON
uptime TEXT -- 运行时间
listen_ports TEXT -- 监听端口列表,逗号分隔
ssh_synced_at DATETIME -- 最后一次同步 SSH 数据的时间
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
services :
id INTEGER PRIMARY KEY AUTOINCREMENT
machine_id INTEGER NOT NULL REFERENCES machines(id) ON DELETE CASCADE
name TEXT NOT NULL -- 服务名称
port INTEGER NOT NULL -- 端口号
protocol TEXT DEFAULT 'TCP' -- TCP / UDP / HTTP / HTTPS
notes TEXT -- 备注
relationships :
id INTEGER PRIMARY KEY AUTOINCREMENT
source_machine_id INTEGER NOT NULL REFERENCES machines(id) ON DELETE CASCADE
target_machine_id INTEGER NOT NULL REFERENCES machines(id) ON DELETE CASCADE
relation_type TEXT NOT NULL -- port_forward / dependency / primary_secondary / custom
source_port INTEGER -- 源端口
target_port INTEGER -- 目标端口
notes TEXT -- 备注
operation_logs :
id INTEGER PRIMARY KEY AUTOINCREMENT
action TEXT NOT NULL -- create / update / delete
entity_type TEXT NOT NULL -- machine / service / relationship
entity_id INTEGER -- 操作对象的 ID
entity_name TEXT -- 操作对象的名称描述
old_value TEXT -- 旧值 (JSON)
new_value TEXT -- 新值 (JSON)
source_ip TEXT -- 请求来源 IP
username TEXT -- 操作用户名admin 或匿名)
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
```
---
## 六、API 设计
### 认证
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/api/auth/login` | 管理员登录(用户名/密码) |
| POST | `/api/auth/logout` | 退出登录 |
| GET | `/api/auth/me` | 获取当前登录状态 |
### 机器
| 方法 | 路径 | 说明 | 权限 |
|------|------|------|------|
| GET | `/api/machines` | 获取机器列表(支持 ?os_type=Linux 筛选) | 访客/管理员 |
| GET | `/api/machines/:id` | 获取单个机器详情含服务管理员额外含关系、IP、MAC、备注 | 访客/管理员 |
| POST | `/api/machines` | 创建机器 | 管理员 |
| PUT | `/api/machines/:id` | 更新机器 | 管理员 |
| DELETE | `/api/machines/:id` | 删除机器 | 管理员 |
| POST | `/api/machines/:id/ssh-info` | SSH 获取系统信息(需传用户名密码,单次有效) | 管理员 |
| POST | `/api/machines/:id/sync-ssh` | 将最近一次 SSH 获取的信息同步到机器记录 | 管理员 |
### 服务
| 方法 | 路径 | 说明 | 权限 |
|------|------|------|------|
| GET | `/api/machines/:machine_id/services` | 获取某机器的服务列表 | 访客/管理员 |
| POST | `/api/machines/:machine_id/services` | 添加服务 | 管理员 |
| PUT | `/api/services/:id` | 更新服务 | 管理员 |
| DELETE | `/api/services/:id` | 删除服务 | 管理员 |
### 关系
| 方法 | 路径 | 说明 | 权限 |
|------|------|------|------|
| GET | `/api/relationships` | 获取全部关系 | 管理员 |
| POST | `/api/relationships` | 创建关系 | 管理员 |
| PUT | `/api/relationships/:id` | 更新关系 | 管理员 |
| DELETE | `/api/relationships/:id` | 删除关系 | 管理员 |
### 日志 / 导入导出
| 方法 | 路径 | 说明 | 权限 |
|------|------|------|------|
| GET | `/api/logs` | 获取操作日志 | 管理员 |
| GET | `/api/export` | 导出数据JSON 下载) | 管理员 |
| POST | `/api/import` | 导入数据(上传 JSON | 管理员 |
### 其他
| 方法 | 路径 | 说明 | 权限 |
|------|------|------|------|
| GET | `/api/health` | 服务健康检查 | 公开 |
---
## 七、已确认的设计决策
| 项目 | 决定 |
|------|------|
| 部署方式 | Web 应用源码部署Linux Systemd 服务 |
| Ping 间隔 | 1 分钟 |
| SSH 系统信息 | 支持,**不保存凭据**,仅密码认证,手动输入用户名密码,单次有效,独立按钮触发,仅管理员可用 |
| SSH 密钥 | **不支持** |
| 自动发现机器 | 不需要,纯手动添加 |
| 用户认证 | **需要**,预设单管理员账号,访客免认证只读访问脱敏数据 |
| 拓扑图 | 保留,力导向图,**仅管理员可见** |
| 导入/导出 | 需要JSON 格式,管理员专属 |
| 操作日志 | 需要,记录所有增删改 |
| 机器规模 | 20 台以内 |
| 前端技术 | Vue 3 + 组件库 + AntV G6 |
| 后端技术 | Go + SQLite |
| 数据自动备份 | **不需要** |
| 前端构建方式 | 支持 embed 打包 + 外置静态目录两种模式 |
---
## 八、待确认细节
1. **前端 UI 组件库**Element Plus 还是 Naive UI或者你有其他偏好
2. **前端构建方式**:把 Vue 打包后的静态文件嵌入 Go 二进制(`embed.FS`,单文件部署),还是前后端分别部署?(建议同时支持两种)
3. **操作日志保留策略**:永久保留还是定期清理(如只保留最近 90 天)?