Appearance
管理者指南
本文档面向机房管理员和运维人员,说明如何使用离线管理工具生成更新包与注册证书,以及如何通过 Flutter 管理客户端完成全部服务端管理操作。离线签名与打包能力可使用独立的 VHDMountAdminTools.exe,也可直接使用 Flutter 管理客户端 Windows 桌面端的"离线工具"页(功能等价、输出文件结构兼容)。
离线工具
离线签名与打包能力当前提供两套等价入口,输出文件结构完全兼容:
- VHDMountAdminTools.exe:独立的 Windows WPF 桌面工具
- Flutter 管理客户端 → 离线工具页(仅 Windows 桌面端可见):4 个标签页(密钥生成、清单打包、证书包、软件部署打包器)
两者均不需要连接服务端,也不应该在机台上执行。下面以独立工具的页签名称叙述,Flutter 管理客户端的标签页一一对应。
生成更新签名密钥
更新包使用非对称签名防止篡改。在发布任何更新之前,你需要先创建签名密钥对。
操作步骤:
- 打开
VHDMountAdminTools.exe - 切换到"签名密钥"页签
- 选择输出目录(默认当前目录)
- 可选填写密钥标识名称(留空则使用日期自动生成)
- 点击"生成签名密钥"
产出文件:
| 文件 | 用途 |
|---|---|
private_key_*.pem | 私钥,妥善保管,仅用于签名更新清单 |
public_key_*.pem | 公钥,可公开 |
trusted_keys.pem | 可信公钥集合,自动追加新公钥 |
私钥泄露会导致任何人都能伪造更新包。建议将私钥存放在加密 U 盘或密码管理器中。
生成更新清单
更新清单描述了一组文件的内容和哈希值,机台客户端通过验证签名确认清单可信后,按清单内容下载并替换本地文件。
操作步骤:
- 将需要分发的文件放入一个目录(称为 payload 目录)
- 切换到"更新清单"页签
- 选择 payload 目录
- 选择输出目录
- 选择更新类型:
- app-update:应用程序更新,有 1GB 大小上限,文件按相对路径部署
- vhd-data:VHD 数据更新,无大小限制,文件直接放入目标根目录
- 填写最低版本要求(独立工具默认 1.7.0;Flutter 端为必填项),机台当前版本低于此值时拒绝更新
- 填写版本号(默认使用时间戳格式
yyyy.MM.dd.HHmmss) - 选择之前生成的私钥文件
- 点击"生成清单"
产出文件:
| 文件 | 用途 |
|---|---|
manifest.json | 更新清单,包含版本、文件列表和 SHA256 哈希 |
manifest.sig | 对清单的签名,客户端用 trusted_keys.pem 验证 |
清单有效期: 默认 3 天。过期后客户端不会执行更新。
机台更新触发方式: 将 manifest.json 和 manifest.sig 放入卷标为 NX_INS 的 USB 设备根目录或 updates/ 子目录,插入机台后客户端自动检测并执行。
生成注册证书包
新机台首次连接服务端时需要提交注册证书完成身份认证。管理员通过离线工具预先签发证书包,分发给部署人员。
操作步骤:
- 切换到"注册证书"页签
- 选择输出目录
- 填写证书包名称(默认
machine-registration) - 填写证书主题名称(默认
VHDMount Machine Registration) - 设置 PFX 密码(至少 8 位)
- 设置证书有效期天数(1 到 3650 天)
- 点击"生成证书包"
产出文件:
| 文件 | 用途 |
|---|---|
*.pfx | 机台客户端使用的证书文件,需配置到 vhdmonter_config.ini |
*.pem | PEM 格式证书,供人工查看 |
*.trust.json | 信任文档,包含指纹和有效期,需导入服务端才能审批该机台 |
*.client-config.ini | 可直接粘贴到客户端配置的配置片段 |
后续操作: 将 .trust.json 中的证书 PEM 内容通过 Flutter 管理客户端导入到"可信注册证书"列表后,持有该证书的机台才能通过审批流程。
Flutter 管理客户端
Flutter 管理客户端是统一的管理入口,支持 Windows、Android 和 iOS。所有服务端管理操作均通过该客户端完成。
首次连接与初始化
首次部署服务端后,必须先完成初始化才能正常使用管理功能。
连接服务端:
- 打开管理客户端,进入连接页面
- 输入服务端地址(如
http://192.168.1.100:8080) - 点击"检查服务状态"
- 若服务未初始化,自动进入初始化向导
初始化向导:
初始化分为三个步骤:准备 OTP、填写配置、完成初始化。
步骤 1 — 准备 OTP:
- 填写 OTP Issuer 和 Account(默认即可)
- 点击"准备 OTP"
- 客户端向服务端请求生成绑定密钥
- 页面显示二维码,使用手机验证器(如 Google Authenticator、Microsoft Authenticator)扫描导入
- 若无法扫码,可使用页面显示的密钥或 URI 手动添加
步骤 2 — 填写配置:
| 字段 | 说明 |
|---|---|
| 管理员密码 | 登录管理后台的密码,需与确认密码一致 |
| Session Secret | 会话加密密钥,可点击骰子图标随机生成 |
| DB Host / Port / Name / User / Password | PostgreSQL 数据库连接信息 |
| 默认启动关键词 | 新机台的默认 VHD 启动关键词(如 SDEZ) |
| 可信注册证书 PEM | 可选,导入预生成的注册证书使其成为可信证书 |
步骤 3 — 完成初始化:
- 在 TOTP 验证码输入框中填入手机验证器当前显示的 6 位数字
- 点击"完成初始化"
- 初始化成功后,使用刚才设置的管理员密码登录
登录
服务端完成初始化后,每次打开管理客户端需要登录。
操作:
- 输入服务端地址
- 输入管理员密码
- 点击"登录"
- 登录成功后进入仪表盘
会话保持: 登录状态通过本地 Session 维持,退出客户端或 Session 过期后需重新登录。
OTP 自动守卫
所有高敏操作(证书管理、机台审批 / 重置、EVHD 明文读取、部署管理、TOTP 密钥管理、日志导出、密码修改、OTP 轮换)在 OTP 未验证或验证已过期时,会被服务端以 requireOtp: true 拒绝。
管理客户端在以下场景自动拦截并触发 OTP 验证窗,用户无需手动寻找入口:
- 进入"可信注册证书"页面时,若 OTP 未验证,自动弹出验证窗
- 任何被服务端以
requireOtp拒绝的操作,自动捕获、弹窗、验证成功后透明地重试原始操作 - 验证失败时在对话框内显示错误,不关闭对话框,可继续输入
- 用户取消时静默返回,不显示额外错误
OTP 自动守卫接管了所有需要二次验证的入口,因此当前界面顶部不再单独提供"验证 OTP"按钮——按需自动弹窗即可。
仪表盘
登录后顶部概览卡片显示四项关键状态:
| 卡片 | 说明 |
|---|---|
| 数据库 | 服务端数据库连接状态 |
| 默认关键词 | 当前全局默认 VHD 启动关键词 |
| OTP | 是否已完成 OTP 验证(高敏操作需要) |
| 当前入口 | 当前连接的服务端地址 |
页面右上角提供三个快捷操作:
- 验证 OTP:输入手机验证器的 6 位验证码,解锁高敏感操作
- 刷新:重新拉取服务端状态
- 登出:退出当前会话
左侧导航栏(桌面端)或底部导航栏(移动端)包含五个核心功能模块:机器管理、机台日志、证书、审计、设置。在 Windows 桌面端额外多一个"离线工具"入口(移动端完全隐藏)。
机器管理
机器管理是核心运维页面,集中处理所有机台生命周期操作。
机台卡片信息:
每张机台卡片显示:机台 ID、密钥类型、审批状态、当前启动关键词、保护状态、EVHD 配置状态、日志保留策略、最后在线时间、注册证书指纹。
添加机台:
- 点击右上角"添加机台"
- 填写机台 ID(如
MACHINE_001) - 填写启动关键词(默认继承全局默认值)
- 确认添加
审批与保护:
| 操作 | 说明 |
|---|---|
| 审批通过 | 允许该机台连接服务端并获取 VHD 选择结果(需要 OTP 验证) |
| 取消审批 | 临时禁止该机台连接,不会删除记录 |
| 开启保护 | 启用保护检查,机台会定期向服务端报告存活状态 |
| 关闭保护 | 停止保护检查 |
配置操作:
| 操作 | 说明 |
|---|---|
| 设置启动关键词 | 修改该机台的 VHD 启动关键词,如从 SDEZ 改为 SDGB |
| 设置 EVHD | 配置该机台的 EVHD 加密磁盘密码 |
| 读取明文 | 查看已保存的 EVHD 密码(需要 OTP 验证 + 填写查询原因) |
| 日志保留 | 单独设置该机台的日志保留活动日数,留空则继承全局默认值 |
| 重置注册 | 清除该机台的注册密钥信息,机台需重新提交注册证书 |
删除机台:
点击"删除机台",确认后永久移除该机台的管理记录和已保存的 EVHD 密码。已上传的机台日志不会自动删除。
快捷入口:
机台卡片上提供两个快捷链接:
- 查看机台日志:直接跳转到机台日志页面并自动筛选该机台
- 查阅审计日志:直接跳转到审计页面并自动筛选该机台
机台日志
机台日志页面用于查看和分析所有机台通过 WebSocket 实时上传的运行日志。
页面布局(桌面端):
三栏布局:左侧会话列表、中间日志明细、右侧原始文本详情。
筛选条件:
| 筛选器 | 说明 |
|---|---|
| 机台 | 只显示指定机台的日志 |
| 会话 | 只显示指定会话的日志(会话代表一次客户端启动周期) |
| 级别 | debug / info / warn / error |
| 组件 | 日志来源组件名称 |
| 事件键 | 日志事件类型标识 |
| 关键词 | 在 message、rawText、metadata 中全文搜索 |
| 开始时间 / 结束时间 | ISO 8601 格式的时间范围,如 2026-04-19T12:00:00Z |
会话卡片: 显示会话 ID、启动时间、最近日志时间、日志总数、Warn 数量、Error 数量。点击会话卡片切换查看该会话的日志明细。
日志明细卡片: 显示日志消息、时间、组件、事件键、级别、序列号。点击卡片在右侧查看完整的原始文本和 Metadata。
操作按钮:
- 应用筛选:按当前条件查询日志
- 清空筛选:重置所有条件
- 刷新日志:重新加载当前筛选结果
- 导出原始文本:将当前筛选结果导出为纯文本,适合保存或发送给开发者分析
- 加载更多日志:当日志数量超过单页限制时,点击加载下一页
证书
证书管理用于维护可信注册证书列表。只有列表中的证书签发的机台注册请求才能被审批通过。
OTP 要求: 证书管理属于高敏感操作。进入页面或执行任何操作时,若 OTP 未验证,会自动弹出 OTP 验证窗(参见上文"OTP 自动守卫"),无需手动点击"验证 OTP"。
导入证书:
- 点击"导入证书"
- 填写证书名称(如
machine-registration) - 粘贴证书的 PEM 文本内容(以
-----BEGIN CERTIFICATE-----开头) - 确认导入
生成证书(仅 Windows 桌面):
PageHeader 中的"生成证书"按钮可一站式完成本地签发 + 服务端导入:
- 点击"生成证书",弹出对话框
- 填写:bundleName、subjectCN、PFX 密码(≥ 8 位)、validDays(1–3650)、输出目录
- 客户端调用
CertificateGeneratorService在本地生成完整证书包(.pfx/.pem/.trust.json/.client-config.ini) - 生成成功后,客户端自动以生成出的 PEM 调用
addTrustedCertificate(bundleName, certificatePem)导入服务端 - 导入成功后自动刷新证书列表
- 若服务端导入失败,显示警告但保留本地文件,可手动通过"导入证书"再试
删除证书:
点击证书卡片上的删除图标,确认后移除。已审批的机台不受影响,但新机台若使用已删除的证书将无法通过审批。
审计
审计日志记录所有管理操作,包括初始化、登录、机台增删改、证书操作、密码修改等。
筛选:
- 按机台过滤:下拉选择机台 ID,只显示涉及该机台的操作
- 搜索:全文搜索机台 ID、事件键、原因等关键词
- 清除机台过滤:恢复显示全部审计记录
审计记录内容:
每条记录显示:操作标题、描述、时间、操作主体、结果、来源 IP、接口路径、事件键。成功操作标记为绿色,失败标记为红色。
设置
设置页面包含五个模块:日志保留策略、服务设置、TOTP 密钥管理、更换 OTP 绑定密钥、修改密码。
日志保留策略:
| 字段 | 说明 |
|---|---|
| 默认保留活动日数 | 有日志写入的活动日保留数量,非自然日 |
| 每日巡检小时 / 分钟 | 服务端执行日志清理的每日定时(0-23 时,0-59 分) |
| 服务端时区 | IANA 时区,如 UTC 或 Asia/Shanghai |
活动日志日说明:机台长时间离线时,不会因为自然时间流逝而提前清理旧日志。只有当日有日志写入时才会计为一个活动日。
服务设置:
- 默认启动关键词:修改全局默认值,影响所有未单独设置关键词的新机台
TOTP 密钥管理:
服务端支持多个并行 TOTP 密钥(authenticator 类型)。所有 authenticator 密钥共同决定服务端的 OTP 验证集合,任一密钥生成的验证码都能通过。
每个密钥包含:id、name、type、platform(保留字段,新版客户端只生成 authenticator)、createdAt、lastUsedAt。
历史遗留:若旧客户端曾创建过
type=biometric的密钥,列表里仍能看到并手动注销,但当前版本不再生成新的 biometric 条目,也不会再用本地生物识别快捷生成验证码——所有 OTP 都通过验证码输入完成。
添加认证器:
- 点击"添加认证器",填写密钥名称(如
Google Authenticator (笔记本)),需 OTP step-up - 客户端调用
POST /api/auth/otp/keys(type:authenticator),服务端生成新密钥 - 弹窗显示二维码 + 密钥文本(仅创建时显示一次)
- 使用手机验证器扫码或手动输入密钥
- 点击"已完成绑定"关闭弹窗
注销密钥:
- 点击密钥卡片上的"注销"
- 弹出确认对话框
- 确认后调用
DELETE /api/auth/otp/keys/:keyId,需 OTP step-up - 服务端校验:若试图注销最后一个
authenticator类型密钥,会被拒绝并返回错误
列出密钥: 仅需登录态,进入设置页时不会触发 OTP 弹窗。
更换 OTP 绑定密钥:
支持在不中断服务的情况下轮换 OTP 密钥。
- 输入当前 OTP 验证码
- 可选填写新的 Issuer 和 Account
- 点击"生成新的绑定密钥"
- 页面显示新二维码,在不删除旧绑定的情况下,将新密钥添加到手机验证器
- 输入新密钥生成的验证码
- 点击"验证新绑定并替换旧绑定"
- 验证通过后,旧绑定自动失效,新绑定生效
在整个过程中,旧绑定一直有效,直到新绑定验证通过。如果操作中断,服务仍然可以用旧 OTP 登录。
修改管理员密码:
- 输入当前密码
- 输入新密码(至少 12 位)
- 确认新密码
- 点击"更新密码"
部署管理新功能
部署管理页面用于向机台分发配套工具软件、配置文件或其他辅助文件。
1. 上传部署包
- 进入“部署管理”页面
- 点击“上传部署包”
- 填写:
- 包名称
- 版本号
- 包类型(
software-deploy/file-deploy) - 签名者
- 选择 ZIP 包文件
- 选择对应的
.zip.sig签名文件 - 提交后,部署包会出现在包列表中
2. 本地打包器
如果你不想手工拼 ZIP 结构,可以直接使用“本地打包器”:
software-deploy:
- 选择安装脚本
install.ps1 - 选择卸载脚本
uninstall.ps1 - 可选填写文件负载目录
- 可选勾选“需要管理员权限”
- 打包后会生成:
name-version.zipname-version.zip.sig
file-deploy:
- 选择文件负载目录
- 填写目标部署路径
targetPath - 可选勾选“需要管理员权限”
- 打包器会自动把文件放进 ZIP 的
payload/子目录
3. 下发部署任务
- 在部署包列表里选定要下发的包
- 进入“部署任务”页
- 选择目标机台
- 创建任务
- 机台端轮询到任务后会自动下载、验签、执行并上报状态
4. 查看机台部署历史
“机台历史”页用于查看单机已经安装过的部署记录:
- 成功 / 失败状态
- 安装时间
- 目标路径
- 软件包版本
5. 触发卸载
对历史记录中已安装的项目,可以直接点击卸载,服务端会给机台创建一条卸载任务,机台端收到后自动执行对应的 uninstall.ps1 或按 fileManifest 删除文件。
强制触发 OTP 二次校验的操作
以下操作当前都属于高敏感操作,管理客户端会在服务端侧强制要求 OTP 二次校验:
证书与密码
- 查看可信注册证书列表
- 添加可信注册证书
- 删除可信注册证书
- 在证书页面"生成证书"并自动导入服务端
- 读取机台 EVHD 明文密码
- 修改管理员密码
- 更换 OTP 绑定密钥(先验证旧 OTP,再确认新绑定)
TOTP 密钥管理
- 添加新认证器密钥
- 注销指定密钥
列出当前已绑定的 TOTP 密钥不需要 OTP(接口仅返回 id / 名称 / 类型 / 时间戳等元数据,不含任何 secret),所以打开设置页时不会触发验证窗。
机台注册与审批
- 审批机台注册
- 取消机台审批
- 重置机台注册状态 / 吊销当前注册密钥
部署管理
- 查看部署包列表
- 查看单个部署包详情
- 上传部署包
- 删除部署包
- 创建部署任务
- 查看部署任务列表
- 删除部署任务
- 查看机台部署历史
- 对部署历史记录发起卸载
日志导出
- 导出机台日志原始文本
使用建议
- 日常浏览普通机台列表、查看基础状态时不需要 OTP
- 在准备执行上面这些操作前,建议先在页面右上角点“验证 OTP”,避免操作过程中被 403 打断
- OTP 验证窗口默认有效期较短,长时间停留后需要重新验证
日常运维流程
发布更新包
适用场景: 发布客户端新版本、更新 VHD 数据内容。
- 准备 payload
- 将更新文件放入一个目录
- app-update:保持目录结构,客户端按相对路径部署
- vhd-data:文件直接放入目标根目录
- 生成签名(使用 VHDMountAdminTools)
- 选择 payload 目录和输出目录
- 选择更新类型
- 填写最低版本要求
- 使用私钥生成
manifest.json+manifest.sig
- 分发
- 将两个文件放入卷标为
NX_INS的 USB 设备 - 插入机台,客户端自动检测并执行更新
- 将两个文件放入卷标为
- 验证
- 通过 Flutter 管理客户端查看机台状态
- 或通过审计日志确认更新操作记录
新机台上架
适用场景: 新购置或重装系统的机台首次接入管理网络。
- 签发注册证书(使用 VHDMountAdminTools)
- 生成证书包(.pfx + .trust.json)
- 导入可信证书(使用 Flutter 管理客户端)
- 登录管理客户端,进入"证书"页
- 将
.trust.json中的 PEM 内容导入可信注册证书列表
- 配置机台客户端
- 将
.pfx文件复制到机台 - 将
.client-config.ini中的配置粘贴到vhdmonter_config.ini - 修改
ServerBaseUrl为实际服务端地址 - 修改
MachineId为唯一标识
- 将
- 添加机台记录(使用 Flutter 管理客户端)
- 进入"机器管理",点击"添加机台"
- 填写机台 ID 和启动关键词
- 启动机台
- 运行
VHDMounter.exe或VHDMounter_Maimoller.exe - 客户端自动提交注册证书
- 运行
- 审批机台(使用 Flutter 管理客户端)
- 在机器管理页面找到该机台
- 点击"审批通过"
机台故障排查
机台无法连接服务端:
- 检查机台网络连通性
- 检查
vhdmonter_config.ini中的ServerBaseUrl是否正确 - 检查机台是否已审批
- 检查注册证书是否已过期或被删除
机台日志异常:
- 打开 Flutter 管理客户端,进入"机台日志"
- 筛选该机台,查看最近的 error/warn 级别日志
- 点击异常日志查看原始文本详情
- 必要时导出日志发送给开发者
EVHD 挂载失败:
- 确认机台已配置 EVHD 密码(机器管理 → 设置 EVHD)
- 确认
encrypted-vhd-mount.exe存在于机台目录 - 查看机台日志中的
EVHD_MOUNT相关错误
需要紧急查看密码:
- 登录 Flutter 管理客户端
- 完成 OTP 验证
- 找到目标机台,点击"读取明文"
- 填写查询原因(如
support investigation) - 密码以弹窗形式显示,可复制
安全注意事项
- 私钥保管:更新签名私钥一旦泄露,攻击者可伪造更新包植入恶意代码
- 密码强度:管理员密码至少 12 位;PFX 密码至少 8 位
- OTP 验证:高敏感操作(证书管理、生成证书自动导入、EVHD 明文读取、机台审批/重置、部署管理、TOTP 密钥管理、日志导出、密码修改)必须完成 OTP 验证;未验证时管理客户端会自动拦截并弹出验证窗
- 多 TOTP 密钥:建议至少保留两个
authenticator类型密钥,避免单一手机丢失导致无法登录 - 审计追踪:所有管理操作均记录审计日志,包括操作者、时间、IP、结果
- 证书有效期:注册证书有效天数允许范围为 1 到 3650 天,建议根据实际部署周期设置