# 主机配置与认证 > 定位:主机从哪里来、如何存储、如何在面板中管理。 ## 来源与优先级 两类来源,按优先级: | 来源 | 位置 | 可编辑 | | --- | --- | --- | | 主机存储(优先) | `$DSH_HOME/dsh-ssh.json` | 是(面板增删改) | | OpenSSH 配置(回退) | `~/.ssh/config` | 否(只读) | 与存储同名的主机以存储为准,列表里也只出现一次(呈现为存储条目)。 存储文件读不懂时按空列表降级(不阻塞 `~/.ssh/config` 的主机),但**编辑** 时会明确报错,避免把读不懂的内容覆盖掉。 ## 存储格式 `dsh-ssh.json` 是共享格式(`{ "version": 1, "hosts": [...] }`),DSH 的 SSH 工具链共用这一份主机列表。插件写入时保留顶层与条目里**不认识的字段**; 写入是原子的(暂存文件 + rename),文件权限收紧为 `0600`(目录 `0700`)。 除 `hosts` 外,文件另有 `knownHosts` 段记录主机密钥指纹(见「主机密钥校验」) 与 `secrets` 段保存加密后的凭据(见「认证与凭据」)。 条目字段: | 字段 | 含义 | | --- | --- | | `alias` | 别名(用于 `ssh://` 与工具参数) | | `host` / `port` / `user` | 连接目标;默认端口 22 | | `auth` | `{ kind: "key" \| "password" \| "agent", keyPath?, passphrase?, password?, agentPath? }` | | `description` / `tags` | 备注与标签(`ssh_workspace_hosts` 可搜索) | | `proxyJump` | 非空时解析明确拒绝(见下) | | `createdAt` / `updatedAt` | 时间戳 | ## ~/.ssh/config 回退 只解析**具体的 `Host` 块**(含通配符的块忽略),读取 `hostname` / `port` / `user` / `identityfile`(`%d` 展开为家目录)/ `password` / `identityagent`, 同键按 OpenSSH 的 first-wins 规则。`Include` / `Match` / 通配符块会被跳过 而不是猜着解析——目标是「够用的回退」,不是完整解析器。 ## 认证与凭据 - 密码与私钥口令**加密后**保存在 `dsh-ssh.json` 的 `secrets` 段,按别名存放: `{ "": { "password": "enc:v1:…", "passphrase": "enc:v1:…" } }`; - 算法 AES-256-GCM,密钥是 `$DSH_HOME/dsh-ssh.key`(`0600`)里的 32 字节随机值, 首次保存凭据时生成。密钥与存储**分文件**:只拿到 `dsh-ssh.json` 解不开内容; 密钥文件丢失或被更换后,已有凭据无法解密,连接时会明确报错,在面板重新保存 该主机即可恢复; - 老版本写入的明文凭据由插件在**启动时自动加密回写**(每次启动检查一次, 无明文则不动文件);`~/.ssh/config` 的 `password` 关键字是只读回退,不会被改写; - **不会回传到浏览器**——面板编辑时密码/口令字段永远为空,留空表示保持原值; - 切换认证方式(key ↔ password ↔ agent)时无法把旧凭据带过去,必须当场填新凭据; - key 认证在主机的 keyPath 不存在时,主机列表会给出 `keyReady: false` 提示(`check-key`)。 > 密文不写进 `auth` 字段,是为了不破坏共享格式:DSH 其它 SSH 工具会把 > `auth.password` 当明文密码直接用。它们读不到本插件保存的密码,但同一主机 > 仍可用密钥 / agent / `~/.ssh/config` 连接。 ## 主机密钥校验(TOFU) 每次连接都校验服务器出示的主机密钥(即 ssh 的 known_hosts 行为): - **首次连接**:把密钥的类型与 SHA256 指纹(连同当时的 host/port、时间) 记入 `dsh-ssh.json` 的 `knownHosts` 段并按别名保存,放行——首次使用即信任; - **指纹一致**:放行; - **指纹不一致**:**拒绝连接**,错误信息同时给出已记录与本次出示的两个 指纹(含记录时间),并提示下一步怎么办; - 面板每张主机卡片都有「**忘记主机密钥**」次级操作(需就地确认):仅在该 主机确实重装系统或合法更换密钥后使用。忘记后,下次连接会重新信任并记录 对方出示的密钥(重新 TOFU),同时丢弃该别名的既有连接。 记录按**别名**归属,存储主机与 `~/.ssh/config` 回退主机一视同仁。升级后的 首次连接会静默记录、无交互确认弹窗——这是有意取舍(在面板流程里插入确认 对话框成本高),因此:**若不确定某次指纹变化是否可信,先按 [troubleshooting.md](./troubleshooting.md) 的「主机密钥不匹配」条目与管理员核对,再决定是否忘记。** ## 面板管理 「远程工作区」面板可添加 / 编辑 / 删除主机(写回 `dsh-ssh.json`)。 改动立即生效:对应别名的旧连接会被丢弃,下一次操作按新配置重连。 删除主机**不会**自动卸载已挂载的远端工作区,但那些工作区会因主机不存在 而无法访问。每张卡片另有「忘记主机密钥」(见上节),只清主机密钥记录, 不动主机条目。 ## 不支持的连接方式 `proxyJump` / `ProxyCommand`(存储字段或 `~/.ssh/config` 里的 `ProxyJump` / `ProxyCommand`):解析时**明确拒绝**并说明原因,而不是静默 按直连去试。需要跳板时请改用别的工具连接。 ## 相关 - [ui.md](./ui.md) - [troubleshooting.md](./troubleshooting.md)