# MShell 安全产品使用说明书

- 文档版本：v0.2.16
- 适用产品：MShell Windows 桌面端、MShell Android 客户端
- 更新时间：2026-09-07

> 本说明书描述当前版本已经实现的安全功能、使用步骤、数据边界和已知限制。MShell 不是经过第三方认证的密码管理器、堡垒机或企业级身份管理系统，不能替代操作系统安全策略、云平台安全策略、网络隔离和专业安全审计。

## 1. 安全定位

MShell 的安全目标是：

- 降低 SSH 会话、SFTP、脚本和密钥管理中的误操作风险。
- 尽量减少密码、私钥和同步 Token 以明文写入本地配置的情况。
- 在连接前验证 SSH 主机指纹，识别主机身份变化。
- 通过会话锁、Android PIN/生物识别保护本机界面。
- 让高风险操作有明确的确认边界，并保留可查询的操作记录。
- 为本机 Agent 提供 SSH 读取、受限查询和由本机开关控制的写入能力。

MShell 的安全边界以“本机设备已经可信、操作系统账户没有被攻破、用户确认的 SSH 主机可信”为前提。若 Windows/Android 设备、用户账户、Agent 进程或远程服务器本身已被入侵，软件层面的保护不能保证数据安全。

## 2. 第一次使用安全配置

建议安装后按以下顺序完成配置：

1. 使用受密码或生物识别保护的 Windows/Android 账户。
2. 在 MShell 中设置会话锁或 Android PIN，并测试锁定、解锁和失败次数限制。
3. 保持 SSH 主机指纹验证开启。
4. 根据风险决定是否保存 SSH 密码；共享电脑或高敏感环境建议关闭保存密码。
5. SSH 优先使用加密私钥，并为私钥设置 passphrase。
6. 在设置中分别确认审计日志和系统日志是否启用。
7. 备份时使用独立且足够强的备份密码；不要把明文 JSON 上传到云端或发送给他人。
8. GitHub/GitLab Token 使用最小权限，并且不要粘贴到终端、脚本、截图或工单中。
9. 本机 Agent/MCP 默认关闭。只有在明确需要时开启，并在使用后关闭。
10. 执行 SSH 加固、防火墙、密钥替换和用户管理脚本前，确认目标终端、当前账号、服务器和回滚方式。

## 3. 数据分类和本地存储

### 3.1 敏感数据分类

| 等级 | 数据                                                                                     | 处理建议                                                   |
| ---- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| 高   | SSH 密码、代理密码、跳板机密码、私钥、私钥 passphrase、GitHub/GitLab Token、同步加密密码 | 不复制到聊天、日志、截图和公共云端；泄露后立即更换或吊销。 |
| 中   | SSH 主机地址、端口、用户名、主机指纹、远程路径、命令片段、脚本                           | 仍可能暴露基础设施信息，应按内部资料管理。                 |
| 低   | 界面主题、窗口布局、非敏感显示偏好                                                       | 可随普通配置迁移，但仍要注意备份文件整体权限。             |

### 3.2 主要本地数据

数据位于 Electron 的用户数据目录中，具体路径由操作系统和 Electron app.getPath('userData') 决定。主要内容包括：

- sessions.json：SSH 会话和连接配置。
- ssh-keys.json、ssh-keys/：SSH 密钥元数据和私钥文件。
- known-hosts.json：已确认的 SSH 主机指纹。
- settings.json：软件设置，其中包含日志、外观、SSH、SFTP 和 Agent/MCP 设置。
- lock-config.json、lock-password.json：桌面端锁定配置和密码派生信息。
- sync-config.json：同步配置和本地保存的同步凭据。
- backup-config.json、backups/：自动备份配置和备份文件。
- logs/、audit-exports/：系统日志、会话日志和审计导出文件。
- terminal-backgrounds/：终端本地背景图附件。

不要直接把整个用户数据目录复制给其他人。备份文件、密钥目录和日志目录都可能包含基础设施信息或敏感内容。

## 4. 本地凭据保护

### 4.1 Windows 桌面端

桌面端通过 Electron safeStorage 保护会话密码、代理密码、跳板机密码、passphrase 和同步 Token。在 Windows 上，Electron 通常使用系统凭据保护能力（包括 DPAPI）完成加密。应用运行时为建立 SSH 连接仍需要在内存中使用解密后的凭据。

“不保存密码”设置只影响会话配置中密码和 passphrase 的持久化，不代表用户手动输入的密码不会短暂存在于进程内存中。

### 4.2 安全存储不可用时

当前版本在 safeStorage 不可用时会使用带 b64: 前缀的 Base64 降级格式。Base64 不是加密，拥有本地文件读取权限的人可以还原内容。因此：

- 不要在安全存储不可用的设备上保存生产密码或 Token。
- 关闭保存密码，并移除已有的保存凭据。
- 通过操作系统权限、磁盘加密和账户隔离保护用户数据目录。
- 迁移到支持 Electron 安全存储的环境后重新录入凭据。

### 4.3 SSH 私钥

SSH 密钥管理器会将私钥文件保存到应用数据目录下的 ssh-keys/，生成时使用受限文件权限；私钥是否有 passphrase 由用户选择。备份包含私钥内容时，必须使用加密 .mshell 备份并保护备份密码。

## 5. SSH 连接安全

### 5.1 认证方式

SSH 会话选择“密码”时使用密码认证，选择“私钥”时使用对应私钥认证。两种认证方式应按当前会话配置明确选择，避免把错误密码、错误私钥或跳板机凭据误用于目标主机。

建议生产服务器优先使用：

- 禁止密码登录，仅保留经过验证的公钥登录。
- 私钥设置 passphrase，并限制私钥文件权限。
- 为不同环境、不同人员和不同用途使用不同密钥。
- 定期轮换密钥，删除离职人员和已泄露密钥对应的远程公钥。

### 5.2 主机指纹验证

首次连接或检测到主机指纹变化时，MShell 会显示主机、端口、密钥类型、指纹以及原有指纹（如果有）。

正确流程：

1. 在服务器控制台、云厂商控制台或可信管理员处获取目标服务器的 SSH 主机指纹。
2. 将可信来源的指纹与 MShell 弹窗中的指纹逐字符核对。
3. 一致时选择“信任并连接”。
4. 不一致、无法核对或服务器刚刚更换系统时，选择取消并先确认变更原因。

关闭“验证主机密钥”后，MShell 会跳过主机指纹校验。该设置只适合明确受控的临时环境，不建议用于生产服务器。

主机指纹文件被删除后，下一次连接会重新进入未知主机流程。主机指纹变化可能表示服务器重装，也可能表示中间人攻击，不能仅因为“能连接”就直接信任。

## 6. 会话锁和本机安全

### 6.1 Windows 桌面端

在“设置 - 会话锁定”中设置锁定密码后，当前版本会在启动时进入锁定状态。可以配置：

- 自动锁定和无操作超时时间。
- 关闭到托盘时锁定。
- 系统休眠时锁定。
- 最大解锁失败次数和锁定时长。
- 手动立即锁定。

桌面端锁定密码不保存明文，而是使用随机盐和 PBKDF2 派生哈希保存。锁定只保护 MShell 界面和操作入口，不会自动断开已经建立的 SSH 连接，也不能阻止具有本机高权限的进程读取内存或操作系统文件。

共享电脑上建议同时启用 Windows 锁屏、磁盘加密和 MShell 会话锁。

### 6.2 Android 客户端

Android 端安全锁支持：

- PIN：随机盐和 PBKDF2-SHA256 派生哈希，不保存明文 PIN。
- 生物识别或设备凭据：通过 AndroidX Biometric 调用系统验证。
- 启动锁定和恢复前锁定。

移动设备丢失时，应立即吊销或更换相关 GitHub/GitLab Token，轮换 SSH 密钥和服务器密码，并在其他可信设备上删除旧同步配置。

Android 导入数据后会保存在应用本地数据中，当前不能按 Windows safeStorage 的保护强度等同理解。请使用系统屏幕锁、设备加密、应用隔离，并避免在已 Root 或不可信设备上导入生产私钥。

## 7. 备份和恢复安全

### 7.1 加密 .mshell 备份

“备份与恢复”生成的 .mshell 文件会使用用户输入的备份密码进行整体加密。备份内容可能包括：

- SSH 会话、密码配置和代理/跳板机配置。
- SSH 私钥内容和公钥内容。
- 命令片段、懒人脚本、命令历史和工作流。
- 端口转发、任务、设置、日志、审计记录和传输记录。
- AI 配置、聊天历史和终端背景图附件。

使用建议：

1. 使用不同于 Windows 登录密码、SSH 密码和同步密码的备份密码。
2. 备份密码使用密码管理器保存；MShell 无法恢复遗失的备份密码。
3. 备份文件放在受限目录或加密磁盘中。
4. 迁移前先确认目标设备可信，再选择需要恢复的数据类别。
5. 恢复后检查会话地址、认证方式、主机指纹、密钥和同步配置。
6. 旧设备不再使用时，删除本地备份和用户数据，并轮换高敏感凭据。

### 7.2 明文 JSON

普通 JSON 备份或解密后的备份数据可能包含会话、命令、密钥和设置，不能视为安全文件。仅在受控的本地临时迁移场景使用，传输完成后立即删除，并清理回收站、临时目录和聊天附件。

### 7.3 当前加密限制

当前备份和同步数据使用 scrypt + AES-256-CBC。该实现没有独立的认证标签或 MAC，不能把它宣传为完整的防篡改格式。同步数据中的 SHA-256 截短校验值主要用于变化检测和同步决策，也不能替代认证加密。

因此，高风险场景还应使用加密磁盘、受控文件权限、可信传输通道和外部文件完整性管理。不要把备份文件放在公开 Gist、公共网盘或任何不受控的目录中。

## 8. GitHub/GitLab 同步安全

远程同步流程：

1. 在设置中选择 GitHub Gist 或 GitLab Snippet。
2. 使用最小权限 Token 验证账户。
3. 查找已有的 MShell 同步文件，或创建新的私有 Gist/Snippet。
4. 设置独立的同步加密密码。
5. 执行上传、下载或智能同步。
6. 在另一台设备上配置同一远程地址、Token 和同步加密密码。

当前正常上传流程要求同步加密密码；同步 envelope 的 encrypted 字段应为 true。如果某个同步文件显示为明文，视为敏感数据暴露，应立即删除远程文件、撤销 Token 并重新生成同步数据。

智能同步（桌面端“智能同步”、移动端“同步”）按记录逐条三方合并：每次同步成功后，本机会保存一份“上次同步结果”作为基准（桌面端为 `sync-base-github.enc` / `sync-base-gitlab.enc`，移动端保存在本地存储，均使用同步加密密码加密）。下次同步时，本机数据和云端数据分别与基准比较：

- 只有一边新增、修改或删除某条记录：采用这一边的变化，删除也会同步到另一边。
- 两边都修改了同一条记录且内容不同：保留 `updatedAt` 较新的版本；没有时间信息时保留本机版本。结果中会列出冲突项。
- 一边删除、另一边修改：保留修改后的版本，避免丢数据，并列为冲突。
- 连接次数、最近连接时间、端口转发运行状态、计划任务执行计数等运行时字段不算修改。
- 应用设置、锁屏配置、AI 配置按字段合并；同一字段两边都改时保留本机值。
- MCP / Agent 接入设置（`settings.agentMcp`，包括端口、令牌和权限模式）只保存在本机，不再上传，也不会被云端数据覆盖。
- 一次同步将删除某类本地数据过半（且至少 5 条）时，会先弹窗确认，取消则本地不做任何改动。
- 上传前会再次检查云端；如果期间被其它设备改过，会自动重新合并（最多 3 次）。

首次合并同步（本机没有基准，或换了同步密码导致基准无法解密）时只新增和覆盖，不删除任何本地数据，然后上传合并结果。

“上传（覆盖云端）”和“下载（覆盖本地）”是不合并的强制操作：上传以本机数据为准覆盖云端；下载把云端记录新增/覆盖到本地，但不删除本地多出的记录。移动端“上传本地”只覆盖会话、分组、片段、快捷命令和密钥，桌面端独有的数据（非 SSH 会话、端口转发、设置、AI 等）会从云端原样保留。

已知限制：

- 同一条记录在两台设备上都被修改时，较旧的那次修改会丢失（只在结果中提示）。
- 未升级的旧版客户端仍会整份覆盖云端，混用时它的上传可能覆盖其它设备的修改；所有设备应升级到支持逐条合并的版本。旧版移动端上传的数据，桌面端只合并会话、分组、片段、快捷命令和密钥。
- 合并以记录 id 区分（懒人脚本以文件名区分）。桌面端首次合并时，名称、主机和用户名都相同的会话会被视为同一条；移动端首次合并只按 id 匹配，各自新建的相同服务器会作为两条会话保留，需要手动删除重复项。
- 同步不是实时的，仍需手动或按自动同步间隔触发；执行强制下载或上传前应先做本地备份。

GitHub/GitLab Token 只用于访问远程同步服务，不等于同步数据加密密码。Token 泄露后远程账户可能被访问或修改；同步密码泄露后远程数据可能被解密，两者都应单独保护和轮换。

## 9. 日志和审计

### 9.1 系统日志

系统日志记录连接错误、SFTP 错误、MCP 错误和内部运行信息。当前支持：

- 设置中关闭或开启系统日志。
- 日志文件大小轮转。
- 默认清理超过 30 天的系统日志。
- 读取时最多返回 10000 条日志，避免一次性占用过多内存。

### 9.2 审计日志

审计日志记录会话、文件、密钥、命令、端口转发、备份、设置和 MCP 工具调用等操作，并支持筛选、导出和清空。当前支持关闭或开启审计日志。

日志会对常见的 password、passphrase 和 PEM 私钥块进行脱敏，但脱敏规则不可能识别所有自定义密钥、Token 或业务数据。终端会话日志还可能记录用户输入和服务器输出，因此：

- 不要在终端直接输入 GitHub/GitLab Token、同步密码或私钥内容。
- 执行密码输入、密钥部署和敏感脚本时，不要开启不必要的会话日志。
- 导出日志前检查是否包含主机地址、用户名、路径或业务数据。
- 日志文件与备份文件使用同等的访问权限保护。

## 10. 本机 Agent / MCP 安全接入

本节是完整使用流程。当前 MCP 实现提供会话读取、文件读取、受限查询命令，以及由“设置 - Agent 接入 - 查询/确认/执行”控制的文件写入和修改命令能力。详细工具说明也见 [mcp-readonly.md](mcp-readonly.md)。

### 10.1 功能和边界

MCP 服务默认关闭，启动后只监听：

    http://127.0.0.1:47821/mcp

请求必须携带：

    Authorization: Bearer <MCP 令牌>

可用工具如下：

| 工具                      | 作用                                                       |
| ------------------------- | ---------------------------------------------------------- |
| list_ssh_sessions         | 列出当前状态为 connected 的 SSH 会话。                     |
| get_ssh_connection_status | 读取一个已连接会话的主机、端口、用户名和活动时间。         |
| list_remote_files         | 通过已连接会话的 SFTP 列出远程目录。                       |
| read_remote_file          | 通过 SFTP 读取 UTF-8 文本文件。                            |
| execute_readonly_command  | 执行单条白名单查询命令，并返回命令和标准输出。             |
| discover_database_targets | 发现宿主机与 Docker 中可安全查询的数据库目标。             |
| query_database            | 通过只读模式查询八种已支持数据库，可在 Docker 容器内执行。 |
| write_remote_file         | 确认模式批准后或执行模式下写入远程 UTF-8 文本文件。        |
| execute_command           | 确认模式批准后或执行模式下执行修改命令并返回输出。         |

MCP 不提供：

- 查询模式下的文件写入或修改命令。
- 直接控制现有交互式终端输入流。
- 独立暴露 SSH 密码、私钥、passphrase、代理凭据和 Electron IPC。

确认模式下，`write_remote_file` 和 `execute_command` 会等待 MShell 用户逐次批准。执行模式下，`execute_command` 可以直接执行任意远程 Shell 命令，包括删除文件、安装软件、修改权限、重启服务和调整防火墙。权限模式是本机能力控制，不是额外身份认证；执行模式期间，任何持有 MCP Token 的客户端都可以调用写入工具。

必须把使用该 MCP 的本机 Agent 当作可信本地程序管理。读取工具可能暴露配置、日志和代码；写入工具可能直接改变服务器状态。MCP Token 泄露时，应同时按远程读取和写入权限泄露处理。

### 10.2 启用 MCP 服务

1. 打开 MShell 的“设置”。
2. 进入“Agent 接入”。
3. 确认当前设备是可信设备，且没有不需要的本地 Agent 正在运行。
4. 打开“启用 MCP 服务”。
5. 确认界面显示“服务运行中”。
6. 复制服务端点和访问令牌；令牌不要发送到远程终端或公共聊天。

服务只绑定本机回环地址，不能直接被局域网设备访问。不要使用端口映射、反向代理、内网穿透或防火墙规则把该端口暴露到其他设备。

### 10.3 在 Codex 图形界面中添加

如果使用 Codex 的“连接至自定义 MCP”页面，请选择“流式 HTTP”（Streamable HTTP），不要选择“STDIO”。MShell 已经作为本机 HTTP 服务运行，不需要 Codex 再启动一个命令行进程。

按以下内容填写：

| 字段                | 推荐的直接标头模式                  |
| ------------------- | ----------------------------------- |
| 名称                | `MShell`，也可以使用其他名称        |
| 类型                | `流式 HTTP`                         |
| URL / 服务端点      | `http://127.0.0.1:47821/mcp`        |
| Bearer 令牌环境变量 | 留空                                |
| 标头键              | `Authorization`                     |
| 标头值              | `Bearer <MShell 中复制的 MCP 令牌>` |

标头值必须包含开头的 `Bearer` 和一个空格。只填写令牌本身会被 MShell 按 `401 Unauthorized` 拒绝。例如，填写 `abc123` 是错误的，填写 `Bearer abc123` 才是正确格式。

也可以选择环境变量模式，但不要与直接标头模式混用：

1. 在启动 Codex 的环境中，将 `MSHELL_MCP_TOKEN` 的值设置为 MShell 中复制的令牌。
2. 在 Codex 的“Bearer 令牌环境变量”字段中填写 `MSHELL_MCP_TOKEN`，这里填写的是变量名称，不是令牌内容。
3. 删除 `Authorization` 标头，避免两个认证来源产生冲突。

填写完成后保存，完全退出并重新打开 Codex，再新建任务加载 MCP 工具。

不要把端点填写到“启动命令”或“参数”中，也不要填写 `npx`、`node`、`python`、工作目录或本地脚本路径。那些字段属于 STDIO 类型，MShell 不使用 STDIO 接入。

### 10.4 使用 Codex CLI 添加

推荐使用 Codex CLI 的环境变量配置命令。先在启动 Codex 的同一个 PowerShell 窗口设置令牌：

    $env:MSHELL_MCP_TOKEN = '<从 MShell 复制的令牌>'
    codex mcp add mshell --url http://127.0.0.1:47821/mcp --bearer-token-env-var MSHELL_MCP_TOKEN
    codex mcp list

也可以手动将以下内容加入 ~/.codex/config.toml：

    [mcp_servers.mshell]
    url = "http://127.0.0.1:47821/mcp"
    bearer_token_env_var = "MSHELL_MCP_TOKEN"

注意：

- PowerShell 环境变量只对当前窗口及其子进程有效。
- 如果从开始菜单或其他图形启动器打开 Codex，该进程可能无法继承上述变量。
- 修改令牌后，需要更新环境变量并重启 Codex。
- 如果已经存在同名配置，应先执行 codex mcp get mshell 检查，不要盲目添加重复服务器。

检查或移除已有配置：

    codex mcp get mshell
    codex mcp remove mshell

STDIO 和流式 HTTP 是两种不同的 MCP 传输方式。STDIO 由 Codex 启动本地命令，通过标准输入输出通信；流式 HTTP 由 MShell 自己运行服务，Codex 通过 URL 和请求头访问。只有接入其他明确提供 STDIO 入口的服务器时，才填写启动命令、参数、环境变量和工作目录。

### 10.5 配置 Claude

在 Claude 支持的 MCP 配置文件中加入以下结构，令牌应替换为当前 MShell 页面中的令牌：

    {
      "mcpServers": {
        "mshell": {
          "type": "http",
          "url": "http://127.0.0.1:47821/mcp",
          "headers": {
            "Authorization": "Bearer <MCP 令牌>"
          }
        }
      }
    }

配置文件包含令牌时，应限制本机账户访问权限。Claude 配置文件被复制、同步或泄露后，视为令牌泄露，立即在 MShell 中重新生成令牌并重启 Claude。

### 10.6 首次连接和验证

完成客户端配置后：

1. 确认至少有一个 SSH 会话已经成功连接，状态不是“连接中”“重连中”或“已断开”。
2. 重启或重新加载 Agent 的 MCP 配置。
3. 让 Agent 先调用 list_ssh_sessions，确认返回的 connectionId、主机、端口、用户名和会话名称。
4. 明确指定要操作的 connectionId，不要让 Agent 根据模糊的主机名猜测目标。
5. 需要读取目录时调用 list_remote_files，传入明确路径。
6. 需要阅读文本时调用 read_remote_file，传入明确文件路径。
7. 需要查询系统状态时调用 execute_readonly_command，传入一条白名单查询命令。
8. 需要修改时，在“Agent 接入”中选择“确认”；明确授权的连续任务可临时选择“执行”。
9. Agent 可调用 write_remote_file 或 execute_command 连续完成本次任务，不需要逐次传入写入参数。
10. 重要配置建议先读取旧内容或备份，完成后重新读取或查询验证结果。
11. 任务结束后切回“查询”，并检查输出中是否包含不应离开本机的业务数据。

推荐先发送以下请求，让 Agent 只列出会话，不执行任何操作：

    请调用 list_ssh_sessions，列出当前已连接的 SSH 会话。
    不要执行命令，不要修改文件。
    只返回 connectionId、主机、端口、用户名和会话名称。

从返回结果中确认目标服务器后，再明确指定 `connectionId`：

    使用 connectionId="这里填写已确认的 ID"。
    不要执行命令，不要修改文件。
    请读取 /etc/os-release，只告诉我文件是否存在，不要输出文件内容。

当前没有单独的文件存在性工具；判断文件是否存在会通过 `read_remote_file` 的读取结果完成。Agent 不应根据主机名、用户名或列表顺序自行猜测目标会话。

查询命令示例：

    使用 connectionId="这里填写已确认的 ID"。
    调用 execute_readonly_command 执行 df -h，并根据返回的 output 总结磁盘使用情况。
    不要修改文件，不要执行其他命令。

`execute_readonly_command` 会返回实际执行的 `command`、可供 Agent 分析的 `output`、完整输出字节数 `outputBytes` 和截断状态 `truncated`。

写文件示例：

    使用 connectionId="这里填写已确认的 ID"。
    Agent 权限为“确认”或“执行”。
    调用 write_remote_file，把完整新内容写入 /etc/example.conf。

修改命令示例：

    使用 connectionId="这里填写已确认的 ID"。
    Agent 权限为“确认”或“执行”。
    调用 execute_command 执行 systemctl restart nginx。
    读取返回的 output 并告诉我执行结果，不要执行其他命令。

### 10.7 工具调用规则

Agent 应遵循以下顺序：

1. list_ssh_sessions
2. 用户确认目标 connectionId
3. get_ssh_connection_status（需要确认状态时）
4. list_remote_files、read_remote_file 或 execute_readonly_command
5. 用户选择“确认”并逐次批准，或选择“执行”后，才调用 write_remote_file 或 execute_command
6. 当前任务完成后切回“查询”

约束：

- 目录最多返回 2000 项。
- 单个文本文件最多读取 1 MiB。
- read_remote_file 适合 UTF-8 文本，不适合二进制文件、大型数据库、私钥归档或无限增长的日志。
- 查询命令每次只能执行一条，最长 2000 个字符；默认超时 10 秒，最大 20 秒。
- 查询输出最多向 Agent 返回 64 KiB；底层捕获超过 256 KiB 时会终止并返回错误。
- 查询命令采用程序和操作白名单，不支持管道、重定向、命令串、Shell 展开、脚本解释器、sudo 和修改类操作。
- write_remote_file 每次最多写入 1 MiB UTF-8 文本；已存在的目标文件会被完整覆盖。
- execute_command 最长 8000 个字符，默认超时 20 秒，最大 120 秒，底层输出捕获上限为 2 MiB。
- 切换为“查询”后，服务端立即拒绝 write_remote_file 和 execute_command；查询与读取工具不受影响。
- 权限模式会保存在本机，重启后仍保持上次状态；“执行”期间任何持有 MCP Token 的客户端都可以调用写入工具。
- 修改命令超时或 MCP 客户端断开时，不能保证远程进程已经停止或自动回滚。
- Agent 只能读取当前已连接会话；断开或重连期间调用会返回不可用错误。
- SSH 自动重连成功后，MShell 会按新的 SSH 客户端重建 SFTP 通道，Agent 需要重新确认会话状态。
- MCP 服务当前运行在 MShell Windows 桌面端；Android 端不能作为 MCP HTTP 服务端。
- MCP 服务端点只监听本机 `127.0.0.1`。不要通过端口转发、反向代理、内网穿透或防火墙把 `47821` 端口暴露给其他设备。
- MCP 令牌不是 SSH 密码，也不是同步加密密码；三者必须分别保管。
- 读取配置文件、日志、代码和命令输出仍可能暴露业务数据，只允许 Agent 获取完成当前任务所需的最小信息。

### 10.8 停止服务和令牌轮换

使用完成后：

1. 回到“设置 - Agent 接入”。
2. 关闭 MCP 服务，确认显示未运行。
3. 如果令牌曾经出现在日志、截图、配置分享、聊天或不可信进程中，点击“重新生成”。
4. 更新 Codex 环境变量或 Claude 配置，并重启对应 Agent。
5. 检查审计日志中的 mcp.tool_call 记录。

重新生成令牌会使旧令牌失效；已经接入的 Agent 必须更新配置才能继续使用。

### 10.9 MCP 故障排查

| 现象或状态码               | 原因和处理                                                                |
| -------------------------- | ------------------------------------------------------------------------- |
| 401 Unauthorized           | 未携带令牌、令牌错误或令牌已重新生成。重新复制令牌并重启 Agent。          |
| 400 Invalid host           | 请求不是发往允许的本机 Host，检查是否使用本机端点。                       |
| 404 Not found              | 路径错误，必须使用 /mcp。                                                 |
| 405 Method not allowed     | MCP 接入需要使用 POST，由客户端负责发送。                                 |
| 413 Request body too large | 请求超过 2 MiB，减少不必要的请求内容。                                    |
| 工具列表为空或没有会话     | MCP 只列出状态为 connected 的 SSH 会话；先连接目标主机。                  |
| 目录读取失败               | 检查 SSH 是否仍连接、SFTP 是否可用、路径是否正确以及远程账号权限。        |
| 重连后读取失败             | 等待 SSH 状态恢复为 connected 后重试；MShell 会按新客户端重建 SFTP 通道。 |
| Codex 提示未找到令牌       | 在启动 Codex 的同一 PowerShell 窗口重新设置 MSHELL_MCP_TOKEN。            |
| Claude 认证失败            | 检查 JSON 配置、Authorization 拼写、令牌是否过期，并重启 Claude。         |

## 11. 高风险功能使用规范

### 11.1 懒人脚本

懒人脚本会在远程 SSH 终端执行命令或部署脚本文件。它不是安全沙箱。执行前必须：

- 确认目标终端和服务器名称。
- 阅读脚本预览，确认变量、端口、用户和路径。
- 了解脚本是否修改 SSH 配置、防火墙、用户、密钥或服务状态。
- 对 SSH 端口修改提前准备备用连接或云厂商控制台。
- 对关闭 SSH 密码登录的脚本，先验证目标账号已有可用公钥，否则不要执行。
- 执行后检查退出码、服务状态和新连接路径。

### 11.2 防火墙和 SSH 端口

修改 SSH 端口与防火墙放行属于可能导致服务器失联的操作。必须确认：

- 云厂商安全组、系统防火墙和 IPv4/IPv6 规则都已考虑。
- TCP、UDP、端口范围和来源 IP 段没有填错。
- 规则是否持久化，重启后是否仍然存在。
- 新端口连接已成功验证后，再关闭旧端口。

终端顶部的防火墙面板会优先选择当前服务器的主要管理方式。`iptables (nf_tables)` 与 nftables 属于同一底层规则体系，不应当作两个独立防火墙重复操作。Docker 发布端口单独展示，不计入主机 INPUT 规则数量。

新增开放规则时默认不填写端口，来源优先选择当前 SSH 来源 IP；选择“所有来源”会在执行前显示风险预览，数据库和缓存端口会显示高风险提示。启用 UFW 或 Firewalld 前，MShell 必须识别当前 SSH 来源 IP 和服务端口，并先创建当前连接保护规则；无法识别时会阻止一键启用。

iptables 新增规则默认开启“重启后继续生效”。MShell 会创建 `/etc/mshell/firewall.rules`、`/usr/local/sbin/mshell-firewall-restore` 和 `mshell-firewall.service`，只恢复经过校验的 `MSHELL-INPUT` 专用链，不使用 `iptables-save`，不保存或覆盖 Docker 动态规则。IPv4 与 IPv6 使用 `iptables` 和 `ip6tables` 分别恢复；关闭该选项的规则会标记为“临时”。

持久化功能不依赖 APT、`iptables-persistent` 或 `netfilter-persistent`，适合软件源暂时不可用但已安装 systemd 和 iptables 的服务器。面板只允许删除 MShell 专用链中的可识别规则，不直接删除其他程序维护的 INPUT 规则。原始规则、工具安装和服务启停位于“系统详情”。云厂商安全组不在 MShell 的检测范围内，仍需在云平台单独核对。

服务器已经安装 UFW、Firewalld 或 iptables 任一可管理工具时，面板不再推荐安装其他防火墙。只有完全缺少可管理工具时才显示安装入口；安装系统软件包仍依赖服务器配置的可信软件源。MShell 会识别仓库元数据过期、仓库不可用和网络解析失败，并停止安装，不会关闭 `Valid-Until`、启用不安全仓库或跳过软件包签名验证。

“规则已持久化”只表示重启后会恢复，不代表其他端口已经关闭。如果 INPUT 默认策略仍为 ACCEPT，未列出的端口依然可能从公网访问，面板会单独显示警告。

### 11.3 SFTP 文件操作

删除、覆盖、重命名、权限修改和批量传输可能影响生产服务。使用前确认远程路径、同名处理策略、备份和恢复方式。下载文件到本地后，也要注意本地杀毒软件、索引服务和备份工具可能读取文件内容。

## 12. 事件响应

### 12.1 密码或 Token 泄露

1. 立即停止相关 Agent、同步和自动任务。
2. 撤销或重新生成 GitHub/GitLab Token。
3. 修改远程服务器密码，或从 authorized_keys 删除泄露密钥。
4. 在 MShell 中重新生成 MCP Token、同步密码和相关会话凭据。
5. 检查审计日志、GitHub/GitLab 操作记录和服务器 SSH 登录日志。
6. 删除包含秘密的截图、日志、临时文件和备份，并清理回收站。

### 12.2 主机指纹变化

不要直接点击信任。通过云控制台、服务器控制台或可信管理员确认是否发生重装、迁移、密钥轮换或系统恢复。确认前不要输入密码、发送私钥或执行命令。

### 12.3 设备丢失

立即执行远程 Token 吊销、SSH 密钥轮换和服务器登录审计。若无法确认设备数据是否可被读取，应把设备上的所有会话凭据、代理凭据、同步 Token 和 MCP Token 都视为泄露。

## 13. 企业内部使用建议

企业内部部署时建议：

- 使用统一的操作系统账户和磁盘加密策略。
- 通过组策略或终端管理工具限制用户数据目录访问。
- 禁止把生产 Token、私钥和明文备份放入公共共享目录。
- 使用专用 SSH 密钥和最小权限远程账号，避免多人共用 root 密码。
- 对高风险脚本建立审批、复核和回滚流程。
- 集中保存或定期导出审计结果，但先检查日志脱敏效果。
- 将 MCP 仅开放给明确批准的本机 Agent，使用完成后关闭服务。
- 通过服务器端日志、云平台审计和 MShell 审计日志交叉核对关键变更。
- 发布前验证签名、版本来源、依赖来源和安装包完整性。

## 14. 安全检查清单

### 日常使用前

- [ ] Windows/Android 设备已启用系统锁屏和设备加密。
- [ ] MShell 会话锁或 Android PIN/生物识别已启用。
- [ ] SSH 主机指纹已核对，验证开关未被无意关闭。
- [ ] 当前会话认证方式和目标服务器正确。
- [ ] 不需要的 MCP 服务、同步和自动任务已关闭。

### 执行变更前

- [ ] 已确认目标 SSH 会话和服务器环境。
- [ ] 已阅读脚本或命令预览。
- [ ] 已准备备份、备用连接或云控制台回滚方式。
- [ ] SSH 端口、防火墙、密钥和用户操作已经过复核。
- [ ] 已确认是否需要审计日志和会话日志。

### 变更完成后

- [ ] 检查命令退出结果和服务状态。
- [ ] 使用新认证方式重新连接验证。
- [ ] 检查防火墙和 SSH 配置是否重启后持久化。
- [ ] 检查审计日志是否记录成功或失败。
- [ ] 删除临时明文文件和不再需要的 Token。

## 15. 当前版本限制和责任边界

- 本地凭据保护依赖操作系统和 Electron safeStorage；不可用时的 Base64 降级不提供保密性。
- 备份和同步的 AES-CBC 数据没有独立认证标签，不能作为防篡改证据。
- 日志脱敏只覆盖常见格式，不能保证识别所有自定义秘密。
- 会话锁保护软件操作界面，不等同于硬件安全模块、远程会话吊销或操作系统级隔离。
- MCP 不会自动判断远程文件、命令输出或写入目标是否敏感，用户必须明确控制 Agent 的读取和写入范围。
- Android 导入后的数据保护取决于设备和应用存储安全，不能直接等同于 Windows DPAPI。
- MShell 不负责验证远程服务器自身的系统安全、云平台安全组、操作系统防火墙或业务数据备份。

发现安全问题时，应保留最小必要日志和复现信息，先撤销受影响凭据，再联系项目维护者。不要在公开 Issue、聊天或截图中上传密码、私钥、Token、完整备份文件或生产服务器地址。
