把 Xshell / Tabby / ~/.ssh/config 的连接配置转成 rssh 可导入的 JSON。纯静态页面,全程在浏览器本地完成,零网络请求 — 主机名、用户名、密钥都不会离开你的机器。
- 打开
dist/index.html(单文件,可直接双击打开,也可挂任意静态托管),右上角可切换中英文。 - 选择来源:
- ~/.ssh/config — 单文件。支持
Host *默认段继承、多把IdentityFile组成的密钥池(下拉选择)、ProxyJump堡垒自动关联(含j1,j2多跳与user@host:port形式)。跳板目标没有自己的 Host 块时(只被通配段罩着),按通配段自动补全一行 —— 跳板写法里的 user/port 优先,与 ssh 解析跳板时看到的完全一致。 - Xshell — 选择
Sessions文件夹(可整个目录拖入)。子目录会变成名称前缀。 - Tabby —
~/.config/tabby/config.yaml。内置私钥(privateKeys 中粘贴的 PEM)直接迁移进 JSON。
- ~/.ssh/config — 单文件。支持
- (可选)挑选私钥文件:按文件名与 IdentityFile 匹配,PEM 内容直接写入 JSON,rssh 导入后即可免重选;未挑选或匹配不到的密钥回退 ssh-agent 认证。
- 勾选条目、检查每行的密钥下拉(默认池中第一把,即 OpenSSH 实际先尝试的),生成 JSON。
- 在 rssh 中:设置 → 导入导出 → 导入文件。增量合并,不影响已有数据。
- 密码不迁移。Xshell/Tabby 的密码是加密存储,网页不做解密;导入后连接时 rssh 会交互询问。
- Xshell 用户密钥:密钥管理器存放在
Documents\NetSarang Computer\<版本>\Xshell\UserKeys(文件名即密钥名)。把整个 Xshell 目录拖进来(含 Sessions 与 UserKeys)即可按名字自动接回私钥;若密钥是 NetSarang/SECSH 私有格式,需先在密钥管理器里导出为 OpenSSH 格式(条目上有 ! 标记提醒)。 - ssh config 的
Include指令暂不拼接,请先合并为单文件。
- 定位:新用户从其它软件一次性迁移到 rssh。每次生成都铸造全新 UUID —— 同一份 JSON 重复导入,rssh 按 id 覆盖不重复;重新生成则是新 id。 工具不做跨会话去重,不用担心多次生成导致数据膨胀。
- 交互:先 parse,用户勾选条目、为每行选择 identity(池中某把 / 内置密钥 / agent)后, 一次性生成 JSON。
- 输出去重:多个 profile 引用同一凭证时,输出里只有一个凭证
(按
(用户名, 密钥)合并,内置密钥按内容区分);堡垒机同理 —— 被多个目标共享或自身也被勾选,都只产生一行 profile。
以上规则由 src/lib/rssh.test.ts 钉死(堡垒两条件、ProxyJump 剥壳与多跳方向、
凭证去重矩阵、8 跳上限、逐次生成全新 UUID)。
npm install
npm test # vitest
npm run dev # 开发服务器
npm run build # 产出单文件 dist/index.htmlConverts connection configs from Xshell / Tabby / ~/.ssh/config into JSON that rssh can import. A purely static page — everything runs locally in your browser, zero network requests. Hostnames, usernames and keys never leave your machine. Toggle Chinese/English in the top-right corner.
- Open
dist/index.html(a single file — double-click it, or host it anywhere static). - Pick a source:
- ~/.ssh/config — a single file. Supports
Host *defaults inheritance, identity pools made of multipleIdentityFiles (dropdown pick), and automaticProxyJumpbastion linking (includingj1,j2chains anduser@host:portforms). A jump target with noHostblock of its own (covered only by wildcards) is synthesized from those wildcard blocks — the user/port written in the jump win, exactly what ssh itself sees when resolving the hop. - Xshell — pick your
Sessionsfolder (dragging the whole directory works). Subfolders become name prefixes. - Tabby —
~/.config/tabby/config.yaml. Embedded private keys (PEMs pasted into privateKeys) migrate straight into the JSON.
- ~/.ssh/config — a single file. Supports
- (Optional) Pick private-key files: they are matched to IdentityFile entries by filename and their PEM content is written into the JSON, so rssh needs no re-picking after import. Unpicked or unmatched keys fall back to ssh-agent auth.
- Check entries, review each row's key dropdown (defaults to the first in the pool — the one OpenSSH actually tries first), generate the JSON.
- In rssh: Settings → Import/Export → Import file. Merges incrementally; existing data is untouched.
- Passwords are not migrated. Xshell/Tabby store them encrypted; this page does not decrypt anything. rssh prompts interactively on connect.
- Xshell user keys live in the key manager at
Documents\NetSarang Computer\<version>\Xshell\UserKeys(files are named after the keys). Drag the whole Xshell directory in (Sessions + UserKeys) and keys are re-attached by name. Keys in NetSarang/SECSH private format must be exported as OpenSSH from the key manager first (flagged with a!on the row). Includedirectives in ssh configs are not spliced — merge into a single file first.
- Positioning: a one-shot migration tool for new users moving to rssh. Every generation mints fresh UUIDs — re-importing the same JSON overwrites by id without duplicating; regenerating produces new ids. The tool never dedupes across sessions, so repeated use cannot bloat your data.
- Interaction: parse first; the user checks entries and picks an identity per row (a pool key / an embedded key / agent), then generates the JSON once.
- Output dedup: profiles sharing a credential get exactly one credential in
the output (merged by
(username, key), embedded keys by content); bastions likewise — shared by several targets or checked itself, still one profile row.
These rules are pinned by src/lib/rssh.test.ts (the two bastion conditions,
ProxyJump decoration stripping and chain direction, the credential dedup
matrix, the 8-hop cap, fresh UUIDs per generation).
npm install
npm test # vitest
npm run dev # dev server
npm run build # emits the single-file dist/index.html