Files
CN_Tool/docs/superpowers/specs/2026-05-21-deploy-linux-ssh-sftp-design.md

15 KiB
Raw Permalink Blame History

Linux 服务器部署运维设计

1. 背景

system-ops/deploy 当前只提供系统部署菜单的基础入口:

  • GET /deploy/overview
  • DeployController
  • DeployService
  • DeployOverviewVO

本次需求是在 deploy 模块中补充 Linux 服务器远程运维能力。用户可以维护 Linux 服务器连接配置,基于 SSH/SFTP 连接服务器,完成远程文件上传、下载和基础命令终端操作。命令终端目标体验接近 Xshell 的基础能力。

当前仓库没有前端代码,本设计只定义页面布局、接口契约、后端模块拆分、数据存储和验证方式,不实现真实前端页面。

2. 范围确认

本期只支持 Linux 服务器。

本期包含:

  • Linux SSH 连接配置的新增、编辑、删除、查询。
  • SSH 连接测试。
  • SFTP 文件列表、上传、下载、删除、新建目录。
  • SSH Shell 基础命令交互。
  • 前端单页运维工作台布局设计。
  • 连接配置使用文件方式存储,不新建数据库表。

本期不包含:

  • Windows 服务器。
  • FTP 协议。
  • 数据库存储连接配置。
  • 部署任务编排。
  • 命令审批、命令黑名单、命令历史。
  • 批量文件压缩下载。
  • 数据库专用客户端封装。
  • Maven 编译、打包、测试。

说明:需求中提到的 “FPT” 本期按 Linux 服务器常用能力理解为 SFTP。SFTP 复用 SSH 账号、密码和端口,比单独 FTP 更适合本期场景。

3. 总体方案

推荐采用 “SSH/SFTP + WebSocket 终端” 方案:

  • 服务器连接配置保存到本地 JSON 文件。
  • 后端通过 SSH 建立 Linux 连接。
  • 文件操作通过 SFTP 通道完成。
  • 终端操作通过 SSH Shell 通道完成。
  • 前端通过 WebSocket 与后端交换终端输入输出。

该方案可以复用同一份服务器连接配置,不需要引入 Windows 远程协议,也能满足类 Xshell 的基础交互需求。

4. 前端页面布局

页面路径建议沿用当前菜单路径:

/systemOps/deploy

页面采用三块工作区:

  • 左侧:服务器列表。
  • 中间:远程文件管理。
  • 右侧:连接详情和快捷操作。
  • 底部SSH 终端区。

推荐布局:

┌──────────────────────────────────────────────────────────────┐
│ 顶部工具栏:新增连接  测试连接  刷新  当前连接状态              │
├──────────────┬──────────────────────────────┬────────────────┤
│ 服务器列表     │ 远程文件管理                    │ 连接详情/操作     │
│              │                              │                │
│ Linux-测试    │ 路径栏:/opt/app               │ 主机/IP          │
│ Linux-生产    │ 上传  下载  新建目录  删除  刷新 │ 用户名           │
│              │                              │ 端口             │
│              │ 文件表格                       │ 测试连接         │
│              │                              │ 打开终端         │
├──────────────┴──────────────────────────────┴────────────────┤
│ 终端 TabsLinux-测试                                         │
│ $ pwd                                                        │
│ /opt/app                                                     │
└──────────────────────────────────────────────────────────────┘

4.1 服务器列表

左侧服务器列表用于选择当前操作目标。

展示字段:

字段 说明
名称 服务器显示名称
主机地址 IP 或域名
SSH 端口 默认 22
连接状态 未测试、连接成功、连接失败

交互:

  • 支持按名称、主机地址搜索。
  • 点击服务器后加载连接详情,并将文件管理区切换到该服务器。
  • 列表项提供编辑、删除、测试连接入口。
  • 删除连接前必须二次确认。

4.2 连接配置弹窗

新增和编辑使用同一个弹窗。

字段:

字段 是否必填 说明
名称 页面展示名称
主机地址 Linux 服务器 IP 或域名
SSH 端口 默认 22范围 1-65535
用户名 SSH 登录用户
密码 新增必填 编辑时留空表示不修改
备注 环境说明

按钮:

  • 测试连接。
  • 保存。
  • 取消。

密码规则:

  • 新增连接时密码必填。
  • 编辑连接时密码不回显。
  • 编辑时密码为空表示沿用原密码。
  • 查询列表和详情接口均不返回密码。

4.3 远程文件管理

中间文件管理区基于当前选中的服务器工作。

顶部路径栏:

  • 展示当前远程目录,例如 /opt/app
  • 支持返回上级目录。
  • 支持点击面包屑跳转到上级路径。

工具栏:

  • 上传。
  • 下载。
  • 新建目录。
  • 删除。
  • 刷新。

文件表格字段:

字段 说明
名称 文件或目录名称
类型 文件、目录、软链接
大小 文件大小,目录可为空
权限 Linux 权限字符串
修改时间 远程文件修改时间

交互规则:

  • 双击目录进入下级目录。
  • 下载只支持普通文件。
  • 删除文件或目录前必须二次确认。
  • 本期支持单文件上传和单文件下载。
  • 上传目标目录为当前路径。
  • 下载目录、批量压缩下载不在本期范围。

4.4 SSH 终端区

底部终端区用于执行 Linux 命令。

交互规则:

  • 点击“打开终端”后创建 SSH Shell 会话。
  • 前端输入通过 WebSocket 实时发送给后端。
  • 后端将 Shell 输出通过 WebSocket 实时推送给前端。
  • 本期建议限制为每台服务器最多一个终端会话。
  • 关闭终端 Tab 时通知后端释放 SSH 会话。
  • 终端断开后显示状态,不自动重连。

用户可以在终端中自行执行数据库命令,例如:

mysql -uroot -p
psql -h 127.0.0.1 -U postgres
redis-cli

后端不解析数据库命令,也不保存命令历史。

5. 后端结构设计

system-ops/deploy 模块内按职责新增类,保留现有 DeployController/deploy/overview

建议结构:

system-ops/deploy/src/main/java/com/njcn/gather/systemops/deploy/
├── config/
├── controller/
├── pojo/param/
├── pojo/vo/
├── pojo/dto/
├── repository/
├── service/
├── service/impl/
└── websocket/

职责拆分:

职责
DeployServerController 连接配置查询、新增、编辑、删除、测试连接
DeployFileController SFTP 文件列表、上传、下载、删除、新建目录
DeployTerminalWebSocketHandler SSH 终端 WebSocket 输入输出转发
DeployServerConfigService 连接配置业务校验和编排
DeployServerConfigRepository JSON 文件读写
DeploySftpService SFTP 文件操作
DeploySshTerminalService SSH Shell 会话创建、输入、输出、关闭
DeployCryptoService 密码加密和解密
DeployProperties deploy 配置项绑定

6. 连接配置存储

连接配置不入库,使用 JSON 文件落盘。存储目录通过配置指定。

建议配置:

deploy:
  storage-dir: ${log.homeDir}/deploy
  terminal-idle-timeout-minutes: 30

deploy.crypto-key 不建议在默认 application.yml 中配置明文值。后续实现时可通过环境覆盖或外部配置提供,业务代码只读取配置,不写死密钥。

落盘文件:

D:\logs\deploy\deploy-server-connections.json

JSON 结构:

{
  "servers": [
    {
      "id": "uuid",
      "name": "测试服务器",
      "host": "192.168.1.10",
      "sshPort": 22,
      "username": "root",
      "password": "加密密文",
      "description": "测试环境",
      "createdTime": "2026-05-21 14:00:00",
      "updatedTime": "2026-05-21 14:00:00"
    }
  ]
}

写文件规则:

  • 启动时如果文件不存在,自动创建空配置文件。
  • 读写方法集中在 DeployServerConfigRepository
  • 写入时先写临时文件,再替换正式文件,避免进程中断导致 JSON 损坏。
  • 保存和删除操作需要加进程内锁,避免并发写入互相覆盖。

密码规则:

  • 密码必须加密后落盘。
  • 接口返回不包含密码。
  • 日志不打印密码。
  • 优先复用项目已有加密能力;如没有合适工具,则在 deploy 内封装 AES 加解密组件。
  • 加密密钥通过配置提供,不在业务代码中硬编码。

7. 接口设计

接口风格沿用当前仓库常见写法:查询和变更优先使用 POST,返回 HttpResult<T>

7.1 连接配置接口

方法 路径 说明
POST /deploy/server/list 查询服务器连接配置列表
POST /deploy/server/add 新增服务器连接配置
POST /deploy/server/update 修改服务器连接配置
POST /deploy/server/delete 删除服务器连接配置
POST /deploy/server/test 测试 SSH 连接

列表返回字段:

字段 说明
id 连接 ID
name 服务器名称
host 主机地址
sshPort SSH 端口
username 用户名
description 备注
createdTime 创建时间
updatedTime 更新时间

新增参数:

字段 是否必填
name
host
sshPort
username
password
description

编辑参数:

字段 是否必填 说明
id 连接 ID
name 服务器名称
host 主机地址
sshPort SSH 端口
username 用户名
password 为空表示不修改
description 备注

7.2 文件接口

方法 路径 说明
POST /deploy/file/list 查询远程目录文件列表
POST /deploy/file/mkdir 新建远程目录
POST /deploy/file/delete 删除远程文件或目录
POST /deploy/file/upload 上传本地文件到远程目录
POST /deploy/file/download 下载远程普通文件

文件列表参数:

字段 是否必填 说明
serverId 服务器连接 ID
path 远程目录路径

文件列表返回字段:

字段 说明
name 文件名
path 完整路径
type FILEDIRECTORYLINK
size 文件大小
permissions 权限字符串
modifiedTime 修改时间

下载接口直接写入 HttpServletResponse。下载文件名沿用远程文件名,不追加日期;仓库“导出或生成文件追加日期”的规则适用于后端生成或导出文件,本功能是下载远程已有文件,不改变原文件名。

7.3 终端 WebSocket

终端连接:

WebSocket /deploy/terminal?serverId={serverId}

前端发送输入:

{
  "type": "input",
  "data": "ls -la\n"
}

前端发送窗口大小:

{
  "type": "resize",
  "cols": 120,
  "rows": 30
}

后端输出:

{
  "type": "output",
  "data": "total 20\r\n..."
}

后端状态:

{
  "type": "status",
  "status": "CONNECTED"
}

异常消息:

{
  "type": "error",
  "message": "SSH连接失败"
}

8. 参数校验

后端至少补充以下校验:

  • 服务器名称不能为空。
  • 主机地址不能为空。
  • SSH 端口范围为 1-65535
  • 用户名不能为空。
  • 新增连接时密码不能为空。
  • 编辑连接时 id 必须存在。
  • 删除连接时 id 必须存在。
  • 同一主机、端口、用户名组合不建议重复保存。
  • 文件路径不能为空。
  • 文件上传目标必须是远程目录。
  • 下载目标必须是远程普通文件。
  • 删除路径不能为空,不能删除空路径或根目录 /
  • 新建目录名称不能为空,不能包含路径分隔符。

9. 安全与资源控制

安全规则:

  • 密码不明文落盘。
  • 接口返回不包含密码。
  • 日志不打印密码、终端输入内容、文件内容。
  • 终端不保存命令历史。
  • 文件路径需要做基础规范化,避免空路径、非法路径和目录穿越。
  • 下载只允许下载普通文件。

资源规则:

  • SSH 连接测试设置连接超时,例如 5 秒。
  • SFTP 操作每次请求创建短连接,操作完成后释放。
  • 终端会话保持长连接,关闭 WebSocket 后释放 SSH Session 和 Channel。
  • 终端会话设置空闲超时,默认 30 分钟。
  • 本期每台服务器最多保留一个终端会话。

10. 依赖建议

后续实现 SSH/SFTP 时建议优先选择 Java 8 可用、项目易接入的 SSH 客户端库,例如 JSch 或 sshj。

选择标准:

  • 支持 SSH 密码登录。
  • 支持 SFTP 文件操作。
  • 支持 Shell Channel。
  • 能在 Spring Boot 2.3 和 Java 8 下稳定使用。

最终依赖需要写入 system-ops/deploy/pom.xml,不影响其他模块。

11. 错误处理

连接测试需要区分常见错误:

场景 返回说明
主机不可达 连接服务器失败
端口不通 SSH端口连接失败
账号或密码错误 SSH认证失败
SFTP 打开失败 文件通道打开失败
终端打开失败 Shell通道打开失败

接口层仍使用项目现有 HttpResultCommonResponseEnum 风格。具体错误文案由 Service 返回给 Controller不新增全局异常体系。

12. 验证方式

默认不执行 Maven 编译、打包、测试命令。后续实现完成后按以下方式验证:

  • 检查 deploy 新增代码只位于 system-ops/deploy
  • 新增连接后,接口返回和 JSON 文件内容一致。
  • 编辑连接时密码留空不会覆盖原密码。
  • 删除连接后JSON 文件同步移除对应记录。
  • 查询接口不返回密码。
  • JSON 文件中密码不是明文。
  • 测试连接能识别成功、主机不可达、端口不通、账号密码错误。
  • 文件列表能展示远程目录内容。
  • 上传文件后远程目录可见。
  • 下载普通文件内容与远程文件一致。
  • 删除文件或目录后远程路径不存在。
  • 新建目录后远程路径存在。
  • 终端能打开 Linux Shell执行 pwdls -lamysql --version 等基础命令。
  • 关闭终端后,后端 SSH 会话被释放。

13. 后续扩展

后续如需求增加,可以在当前方案基础上扩展:

  • SSH 私钥登录。
  • 多终端 Tab。
  • 命令审计和历史记录。
  • 命令黑名单或审批。
  • 部署脚本编排。
  • 文件批量上传和批量下载。
  • Windows WinRM 或 PowerShell Remoting。

这些能力不进入本期实现,避免当前 deploy 模块从基础入口一次扩张为完整运维平台。