news 2026/7/1 9:55:06

用 Rust 写一个不依赖 OpenSSL 的命令行 SSH 工作台:r-shell 实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用 Rust 写一个不依赖 OpenSSL 的命令行 SSH 工作台:r-shell 实战

运维和后端开发里有一类麻烦,不是「连不上服务器」这种大事,而是一堆很小但天天重复的操作:

  • 连上去敲一条命令看看状态,
  • 把一个安装包传上去,
  • 把一份日志拉下来,
  • 瞄一眼 CPU 和内存满没满,
  • 然后在生产、测试、数据库、日志机之间来回切。

每一件单独看都不算事。可一旦机器多起来,系统自带的ssh/scp/sftp各管一摊、IP 和端口靠脑子记、参数每次重敲——这种「碎」就成了真正的时间黑洞。

r-shell 想把这摊碎活收进一个命令行二进制里:connections管连接、exec跑命令、shell开交互终端、upload/download走 SFTP、stats打系统快照。它用 Rust 写内核,SSH 栈是纯 Rust 的russh,不依赖 OpenSSL / libssh,所以 macOS / Linux / Windows 都能出一个零依赖、拷过去就能跑的单文件。

这篇不讲 AI,只讲一件事:怎么把多服务器的日常操作,收敛成一个顺手、可脚本化、带安全默认值的命令行工具。文中每条命令和输出都对应仓库里能跑的实现。

一、它能干什么

一张表先把全貌摆出来:

子命令作用
connections增删改查已保存的主机(存在本地workspace.json)
exec在远程主机上执行单条命令并打印输出
shell打开完整交互式 PTY(vim / htop / less 都能用)
ls列出远程目录
upload/download通过 SFTP 单文件上传 / 下载
stats一次性的 CPU / 内存 / 磁盘 / 网络快照(Linux 与 Windows 通吃)
mcp启动本地 MCP 服务器(可选,本文不展开)

同一个二进制在三大平台都能跑。exec/shell/upload/download适用于任意 POSIX 主机;ls面向 Linux(依赖 GNUls);stats则做了 OS 适配,Linux 读/proc、Windows 走 PowerShell CIM,都能出数。

二、和系统自带的 ssh / scp 有什么区别

常有人问:sshscp不是够用了吗?够用,但 r-shell 解决的是「够用之上的碎」。它的定位看这张表最清楚:

场景传统 ssh / scpr-shell
连接信息管理手写~/.ssh/config或脑子记 IPconnections子命令统一增删改查
执行远程命令ssh user@host "cmd"r-shell exec -c prod -- cmd
文件传输scp单独拼路径upload/download复用同一份连接定义
看负载手动top/df/free各看一遍stats一条命令聚合成一屏
输出面向人眼表格之外都给--json,对脚本友好
安全默认取决于系统与个人习惯内置主机密钥 TOFU、凭据文件0600
分发依赖系统自带纯 Rust 单二进制,零系统依赖,拷了就跑

一句话:r-shell 不是要取代ssh,而是把「连接管理 + 常用操作 + 安全默认 + 可脚本化」打包成一个顺手的工具。

三、技术选型:为什么是 Rust + russh,且不依赖 OpenSSL

三个关键决策:

  • 语言用 Rust。SSH、SFTP、系统采样这些活儿,既要正确又要能扛并发,Rust 的所有权和类型系统能把「连接状态、凭据边界」这类不变量直接编译进类型里,少一类运行期惊吓。
  • SSH 栈用纯 Rust 的russh,而不是去绑 OpenSSL / libssh。这一条对「分发」太关键了:一旦动态依赖 OpenSSL,你在 Windows 上就得操心运行时和版本地狱;改用russh后,整套握手、认证、PTY、known_hosts都在 Rust 里,编出来就是一个零系统依赖的单二进制,拷到一台干净机器上直接能跑。
  • 异步用 tokio。SSH / SFTP 是典型 I/O 密集场景,全程异步;命令行参数与子命令树交给clap的 derive 宏声明,--help自动生成;交互终端的 raw mode 和无回显密码输入交给crossterm

依赖很克制,核心就这几样(coreCargo.toml):

russh # 纯 Rust SSH 协议:握手 / 认证 / 通道 / PTY russh-keys # 密钥与 known_hosts 处理 russh-sftp # SFTP 子系统:文件传输 / 列目录 tokio # 异步运行时 sysinfo # 本机资源采样

CLI 这一层再叠上clap(命令行)和crossterm(终端控制)。全程没有 OpenSSL。

四、架构:CLI 与桌面端共享同一套内核

r-shell 最初其实是个图形界面应用。正因为业务逻辑和界面一开始就解耦,后来重构出命令行版时,几乎零成本复用了全部后端——CLI 和桌面 GUI共用同一个core:同样的连接管理、同样的 SSH 实现、同样的系统采样。你在 GUI 里存的连接,CLI 也认;反过来也成立。

┌───────────────────────────┐ 桌面 GUI ───┤ flutter_rust_bridge (FFI) ├──┐ └───────────────────────────┘ │ ▼ r-shell CLI ───────────────────────▶ core(共享内核) ├── native_backend SSH/SFTP、连接管理器 ├── monitor /proc 与 PowerShell CIM 采样 ├── model SavedConnection / 脱敏 sanitized() └── storage workspace.json(0600)

CLI 入口本身很薄,clap解析完就把活儿丢给core:

cli/ └── src/main.rs # 参数解析、子命令分发、输出格式化(表格 / JSON) core/ └── src/ # native_backend / monitor / model / storage / mcp —— CLI 与 GUI 共用

五、命令实战(附真实输出)

下面按子命令给出可直接复制的示例,输出格式都对应main.rs里真实的打印逻辑。

1. connections —— 像通讯录一样管连接

# 新增一个用公钥认证的连接 r-shell connections add \ --name prod-web --host 203.0.113.10 --username deploy \ --auth publickey --key-path ~/.ssh/id_ed25519 \ --folder Work --description "生产环境 Web 服务器" # 列表(表格) r-shell connections list

表格输出:

ID NAME HOST AUTH FOLDER ssh-1781247286839 prod-web deploy@203.0.113.10:22 publickey Work ssh-1781247290114 test-db root@10.0.0.5:22 password Staging

--json给脚本用,而且是脱敏的——只告诉你有没有密码 / 私钥,绝不回吐明文:

[ { "connection_id": "ssh-1781247286839", "name": "prod-web", "host": "203.0.113.10", "username": "deploy", "port": 22, "auth_method": "publickey", "folder": "Work", "tags": [], "description": "生产环境 Web 服务器", "status": "Disconnected", "has_password": false, "has_private_key_path": true } ]

改字段、删连接也都在一条命令里:

r-shell connections update ssh-1781247290114 --port 2222 --folder Staging r-shell connections remove ssh-1781247290114

2. exec —— 跑一条命令就走

--之后的内容原样发给远端。既能用已存连接(-c),也能临时给--host:

r-shell exec -c prod-web -- uname -a r-shell exec -c prod-web -- "ls -la /var/www && df -h" r-shell exec --host 203.0.113.10 --user deploy -- systemctl status nginx

「连接 → 执行 → 自动断开」一气呵成,特别适合写进巡检 / 部署脚本里批量跑。

3. shell —— 完整交互式终端

raw 模式下的完整 PTY,vimhtopless这类需要伪终端的程序都能正常用。会话卡住时按Ctrl-]强制退出本地循环:

r-shell shell -c prod-web

4. ls —— 列远程目录

r-shell ls -c prod-web /var/log

输出列依次是:类型(DIR/FILE/LNK)、权限、大小、修改时间、名称:

DIR drwxr-xr-x 4096 2026-06-20 14:31 nginx FILE -rw-r--r-- 10240 2026-06-21 09:02 syslog FILE -rw-r--r-- 204800 2026-06-21 08:55 dpkg.log LNK lrwxrwxrwx 24 2026-06-18 02:00 alternatives.log

--json同样可以拿去喂脚本。

5. upload / download —— SFTP 传文件

走 SFTP,不依赖远端有没有scp,只要 SSH 通就能传:

# 本地 -> 远程 r-shell upload -c prod-web ./app.tar.gz /tmp/app.tar.gz # Uploaded ./app.tar.gz -> /tmp/app.tar.gz (12.4 MB) # 远程 -> 本地 r-shell download -c prod-web /tmp/remote.log ./local.log # Downloaded /tmp/remote.log -> ./local.log (843.2 KB)

6. stats —— 一屏看完系统资源

连续采样两次,算出 CPU 占用和网络速率,一条命令出一份快照。Linux 上读/proc:

r-shell stats -c prod-web
OS: Linux 6.1.0 Uptime: 12d 4h 31m CPU: 7.4% (8 cores, load 0.42) Memory: 61.2% (4.9/7.8 GB) Disk: 40.0% (3.8/9.5 GB) Network: down 1.5 KB/s up 320 B/s

同一条命令打到 Windows 主机也能出数——内核里换成一段 PowerShell CIM 采集,自动处理好编码:

OS: Microsoft Windows 11 专业工作站版 10.0.29591 Uptime: 7d 6h 12m CPU: 9.0% (8 cores, load 0.00) Memory: 52.0% (8.3/15.9 GB) Disk: 52.4% (56.3/118.1 GB) Network: down 18.6 KB/s up 2.4 KB/s

六、一次性命令的生命周期:连接 → 执行 → 断开

exec/ls/upload/download/stats都遵循同一套「用完即走」的模型,这也是它适合脚本化的原因:

解析目标(-c 已存连接 / --host 临时主机;缺密码则安全提示输入) ↓ 建立 SSH 连接(握手 → 主机密钥 TOFU 校验 → 密码或公钥认证) ↓ 执行子命令对应的操作 ↓ 自动关闭连接,干净退出

每条命令都自包含、互不残留状态,写进 CI / 巡检脚本里行为可预测。(需要在一条会话里连发多条命令、保持工作目录的场景,则交给shell的交互式 PTY。)

七、面向运维的安全默认值

SSH 工具直连服务器凭据,安全不能是「可选项」。r-shell 把几条底线做成了默认行为:

  • 主机密钥 TOFU(首次信任)。按~/.ssh/known_hosts校验:首次连接记录主机密钥,之后必须一致;一旦对不上(典型的中间人,或主机被换),直接中止连接而不是默默连上去。只有显式传--insecure才跳过——那是留给一次性测试机的,不是日常姿势。
  • 凭据只进不出。密码、私钥路径、口令绝不会被打印;任何连接列表都走sanitized(),只暴露has_password/has_private_key_path这种布尔值。
  • 密码输入不回显。终端进 raw 模式逐字节读取,屏幕上不显形。
  • 配置文件仅属主可读workspace.json在 Unix 上以0600创建、目录0700,不让同机器上别的用户cat到你的跳板信息。

已保存连接的落盘位置:

系统路径
macOS~/Library/Application Support/r-shell/workspace.json
Linux~/.local/share/r-shell/workspace.json
Windows%LOCALAPPDATA%\r-shell\workspace.json

八、安装

源码编译

只需要 Rust 和 Cargo(rustup.rs),不需要 OpenSSL 或 libssh:

git clone https://github.com/MageGojo/r-shell-cli.git cd r-shell-cli cargo build --release --manifest-path cli/Cargo.toml sudo install -m 0755 cli/target/release/r-shell /usr/local/bin/r-shell r-shell --version

不想装,直接跑也行:

cargo run --manifest-path cli/Cargo.toml -- exec -c prod-web -- uptime

预编译包

懒得编译的话,Releases 里有现成的:

平台文件
macOS(Apple Silicon)r-shell-macos-apple-silicon.dmg
macOS(Intel)r-shell-macos-intel.dmg
Windows x64r-shell-windows-x64-installer.exe

macOS 上把二进制拷进PATH后,记得清一下 Gatekeeper 隔离标记:xattr -dr com.apple.quarantine /usr/local/bin/r-shell;Windows 安装器会自动把r-shell加进PATH。因为是没买付费证书的开源软件,首次打开时按系统提示放行即可。

九、顺带一提:它还有个桌面端

抛开命令行,同一套core还撑起了一个 Flutter 写界面的桌面应用:命令块终端(每条命令和它的输出各成一块,带退出码、耗时)、实时监控走势图、SFTP 拖拽、多标签管多台。CLI 适合脚本和远程会话,GUI 适合盯监控和翻历史,两者数据互通。

另外,r-shell mcp还能起一个只绑127.0.0.1的本地 MCP 服务器,让支持 MCP 的工具借一条常驻 SSH 会话干活——那是另一个话题,本文不展开。

十、适合谁

  • 运维 / DevOps:统一管理一堆服务器,批量exec巡检、upload/download发版拉日志,把远程操作写进流水线。
  • 后端开发:快速连测试机执行命令、传安装包,不用每次拼一长串ssh/scp
  • 想要零依赖单文件的人:不想在目标机上装一堆东西,拷一个二进制就能用。
  • Rust 学习者:clap子命令树、russh的 SSH 编程、tokio异步 I/O、known_hosts校验、业务与界面解耦——都是能直接照着读的活例子。

如果你只管一两台机器,它是个顺手的 SSH 工具;如果你要管很多台并写自动化,它的连接管理和可脚本化会更值。

十一、开源与下载

r-shell 已开源(MIT),由极数本源(apizero.cn)· MageGojo出品:

  • 源码:github.com/MageGojo/r-shell-cli
  • 下载:Releases

觉得有用就去仓库点个 star。日常要在多台服务器之间跑命令、传文件、看负载的,可以拿它当一个轻量、安全、可脚本化的 SSH 工作台;在学 Rust 命令行开发的,也很适合作为源码阅读和二次开发的参考。

⚠️免责声明:本项目仅供学习与合法运维使用。SSH / 命令执行 / 文件读写均会对远程主机产生实际影响,使用者应自行确认操作对象与命令内容,并对重要数据做好备份。请仅在你拥有合法授权的主机上使用;使用本工具产生的一切后果由使用者自行承担。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/1 9:52:22

服装供应链交付延期痛点分析:人工优化瓶颈与SCM数字化落地方案

一、行业背景:服装订单交付延期的普遍现状在快时尚、多批次小单、直播电商的行业模式驱动下,2026年服装行业整体供应链交付稳定性仍存在明显优化空间。根据中国服装协会2025年11月发布的《国内服装企业供应链运营现状调研白皮书》统计数据,国…

作者头像 李华
网站建设 2026/7/1 9:47:19

学习做一个眼部按摩仪的DAY1

眼部按摩仪项目设计概述与核心功能介绍项目概述在当下高强度用眼的生活与工作场景中,手机、电脑等电子设备的长期使用,让绝大多数人都面临眼干、眼涩、眼部酸胀、视觉疲劳等问题,眼部亚健康状态愈发普遍。针对这一市场痛点与用户需求&#xf…

作者头像 李华
网站建设 2026/7/1 9:39:37

Ubuntu 20.04 下 MongoDB 备份恢复与迁移实战指南

1. 为什么 MongoDB 备份恢复在 Ubuntu 20.04 上不是“复制文件”那么简单很多人第一次在 Ubuntu 20.04 上部署 MongoDB 后,看到/var/lib/mongodb/目录里一堆.wt文件,下意识就想用cp -r或rsync直接打包走——这恰恰是生产环境最危险的操作起点。我去年帮一…

作者头像 李华
网站建设 2026/7/1 9:38:35

百度网盘直连解析工具:3步实现高速下载的完整指南

百度网盘直连解析工具:3步实现高速下载的完整指南 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 在当今云存储时代,百度网盘已成为国内用户存储和分享…

作者头像 李华