SSHX 基于 Web 的安全协作开源命令行工具
前言⌗
在得知该开源项目以前,我自己就遇到过这方面的需求:
- 在 CI/CD 执行过程中,进入 Gitlab Runner 进行 Debug (项目中有 Github Action 的示例)
- 在团队中协助成员完成一些终端操作 (这个需求可能对于 IT Administrator 感触比较深)
介绍⌗
SSHX 是一款基于 Rust 开发的命令行协作工具,支持多人同时在线协作,使用起来也非常简单,SSHX 的主要功能如下:
- 跨平台
- 简单小巧
- 端到端加密
- 支持多终端
- 全球网络优化
- 支持即使通讯
- 实时显示人员名称和鼠标位置
安装⌗
# 使用安装脚本
curl -sSf https://sshx.io/get | sh
# 或从源码安装
cargo install sshx
使用⌗
分享你的终端给他人:
sshx
sshx v0.2.1
➜ Link: https://sshx.io/s/dStBgdqp7V#GvmVDg46h40BRz
➜ Shell: /bin/zsh
启动后,将生成的链接分享给他人即可,其他人可以基于 Web 在你的终端中进行交互。
首次进入的,需要录入名称:
成员加入后:
Web UI 顶部的工具栏中依次是 Logo、新建终端、Chat、设置和网络状态。
Self-hosted⌗
虽然官方的服务体验还算不错,但是有时候网络抖动还是比较大的,我这边测试的时候网络延迟基本在 ~350ms
左右。
于是我萌生了自建 Server 端的想法,看了一下项目的大致结构,没有提供 docker-compose.yaml 但是有 Dockerfile,那就好办了!
对于想要在内网使用,或者想自建 Server 节点的,可以 Clone 源码,并构建自己的 Docker image。
gh repo clone ekzhang/sshx
cd sshx
docker build -t sshx:latest .
本以为构建完成后,没想到还有两个坑再等着我。
第一个问题是因为端到端加密使用了浏览器提供的 crypto.subtle
接口,如果不满足条件则会导致 JS 执行报错:
crypto.subtle.importKey TypeError: Cannot read properties of undefined
经过一番搜索,发现要使用 crypto.subtle
接口需要满足如下条件中的一个:
- 在安全的上下文中运行,也就是必须使用 HTTPS 提供服务
- 使用 HTTP 提供服务,但是域名只能是 localhost
找到问题就好办了,于是我用 mkcert
生成了 sshx.test
域名的自签名证书,并使用 Traefik 做的反向代理,具体 docker-compose.yaml 配置如下:
services:
sshx:
image: betterde/sshx:latest
labels:
- traefik.enable=true
- traefik.http.services.sshx.loadbalancer.server.port=8051
- traefik.http.routers.sshx.tls=true
- traefik.http.routers.sshx.rule=Host(`sshx.test`)
- traefik.http.routers.sshx.service=sshx
- traefik.http.routers.sshx.entrypoints=http,https
restart: always
hostname: sshx
networks:
- traefik
command: ["./sshx-server", "--port", "8051", "--listen", "::", "--override-origin", "https://sshx.test"]
environment:
- SSHX_SECRET=mylOHBgeQYBnEGkMiY25Q4wEr7Fa7i33
- SSHX_REDIS_URL=redis://redis:6379
container_name: sshx
networks:
traefik:
external: true
启动服务端:
docker compose up -d
[+] Building 0.0s (0/0) docker:orbstack
[+] Running 1/0
✔ Container sshx Running
启动客户端:
sshx --server https://sshx.test
2023-11-30T07:16:31.704375Z ERROR sshx: transport error
Caused by:
0: error trying to connect: invalid peer certificate: UnknownIssuer
1: invalid peer certificate: UnknownIssuer
从错误提示可以看得出是 CA 证书的问题,于是去该项目代码仓扒一扒 Issue,让我找到了这个 Issue。但作者表示暂时没有这方面的打算,那我们就自行替换 CA 然后手动编译客户端。
使用下面命令替换 Cargo.toml
中的 tls-webpki-roots
为 tls-roots
:
# linux
sed -i 's/tls-webpki-roots/tls-roots/g' ./Cargo.toml
# macOS 略微不同,需要在 -i 后 指定备份文件名称,我们这里不需要备份,所以是 ''
sed -i '' 's/tls-webpki-roots/tls-roots/g' ./Cargo.toml
编译 SSHX 客户端:
cargo build --release --bin sshx
Updating crates.io index
Downloaded http-range-header v0.3.1
Downloaded itoa v1.0.9
Downloaded mime_guess v2.0.4
Downloaded matchit v0.7.2
Downloaded async-trait v0.1.73
Downloaded anstyle v1.0.2
Downloaded clap v4.4.2
Downloaded password-hash v0.5.0
Downloaded jobserver v0.1.26
Downloaded bitflags v2.4.0
Downloaded ciborium-io v0.2.1
Downloaded petgraph v0.6.4
Downloaded async-channel v1.9.0
Downloaded rustls-webpki v0.101.4
Downloaded tokio-tungstenite v0.20.0
Downloaded clap_builder v4.4.2
Downloaded pin-project v1.1.3
Downloaded cipher v0.4.4
Downloaded sha1_smol v1.0.0
Downloaded ctr v0.9.2
Downloaded axum-core v0.3.4
Downloaded blake2 v0.10.6
Downloaded proc-macro2 v1.0.66
Downloaded axum v0.6.20
Downloaded h2 v0.3.21
Downloaded syn v2.0.31
Downloaded zstd v0.12.4
Downloaded regex-automata v0.3.8
Downloaded encoding_rs v0.8.33
Downloaded which v4.4.2
Downloaded url v2.4.1
Downloaded zstd-sys v2.0.8+zstd.1.5.5
Downloaded unicase v2.7.0
Downloaded slab v0.4.9
Downloaded serde_path_to_error v0.1.14
Downloaded scopeguard v1.2.0
Downloaded quote v1.0.33
Downloaded pin-project-internal v1.1.3
Downloaded tokio v1.32.0
Downloaded nix v0.27.1
Downloaded regex-syntax v0.7.5
Downloaded tower-http v0.4.4
Downloaded regex v1.9.5
Downloaded aho-corasick v1.0.5
Downloaded serde_json v1.0.106
Downloaded webpki-roots v0.23.1
Downloaded rustls-webpki v0.100.3
Downloaded bytes v1.5.0
Downloaded socket2 v0.5.3
Downloaded serde v1.0.188
Downloaded ryu v1.0.15
Downloaded rustls v0.21.7
Downloaded security-framework v2.9.2
Downloaded unicode-ident v1.0.11
Downloaded concurrent-queue v2.2.0
Downloaded tempfile v3.8.0
Downloaded utf-8 v0.7.6
Downloaded sha1 v0.10.5
Downloaded either v1.9.0
Downloaded tonic-reflection v0.10.0
Downloaded prost-derive v0.12.0
Downloaded prost v0.12.0
Downloaded tonic-build v0.10.0
Downloaded prost-types v0.12.0
Downloaded tonic v0.10.0
Downloaded errno v0.3.3
Downloaded fastrand v2.0.0
Downloaded pin-project-lite v0.2.13
Downloaded serde_derive v1.0.188
Downloaded deadpool-redis v0.13.0
Downloaded clap_lex v0.5.1
Downloaded zstd-safe v6.0.6
Downloaded smallvec v1.11.0
Downloaded redis v0.23.3
Downloaded thiserror-impl v1.0.48
Downloaded inout v0.1.3
Downloaded ciborium-ll v0.2.1
Downloaded equivalent v1.0.1
Downloaded anstream v0.5.0
Downloaded sync_wrapper v0.1.2
Downloaded rustversion v1.0.14
Downloaded pkg-config v0.3.27
Downloaded log v0.4.20
Downloaded prettyplease v0.2.15
Downloaded security-framework-sys v2.9.1
Downloaded deadpool-runtime v0.1.3
Downloaded dashmap v5.5.3
Downloaded itertools v0.11.0
Downloaded thiserror v1.0.48
Downloaded num_cpus v1.16.0
Downloaded deadpool v0.10.0
Downloaded close_fds v0.3.2
Downloaded rustls-pemfile v1.0.3
Downloaded base64ct v1.6.0
Downloaded cpufeatures v0.2.9
Downloaded clap_derive v4.4.2
Downloaded argon2 v0.5.2
Downloaded home v0.5.5
Downloaded hyper v0.14.27
Downloaded memchr v2.6.3
Downloaded tungstenite v0.20.0
Downloaded combine v4.6.6
Downloaded ciborium v0.2.1
Downloaded prost-build v0.12.0
Downloaded httpdate v1.0.3
Downloaded anyhow v1.0.75
Downloaded cc v1.0.83
Downloaded event-listener v2.5.3
Downloaded base64 v0.21.4
Downloaded aes v0.8.3
Downloaded rustix v0.38.12
Downloaded 111 crates (10.1 MB) in 3.06s (largest was `encoding_rs` at 1.4 MB)
Compiling libc v0.2.147
Compiling proc-macro2 v1.0.66
Compiling unicode-ident v1.0.11
Compiling cfg-if v1.0.0
Compiling autocfg v1.1.0
Compiling serde v1.0.188
Compiling pin-project-lite v0.2.13
Compiling version_check v0.9.4
Compiling typenum v1.16.0
Compiling parking_lot_core v0.9.8
Compiling log v0.4.20
Compiling smallvec v1.11.0
Compiling futures-core v0.3.28
Compiling generic-array v0.14.7
Compiling lock_api v0.4.10
Compiling scopeguard v1.2.0
Compiling itoa v1.0.9
Compiling once_cell v1.18.0
Compiling anyhow v1.0.75
Compiling slab v0.4.9
Compiling futures-sink v0.3.28
Compiling futures-task v0.3.28
Compiling either v1.9.0
Compiling tracing-core v0.1.31
Compiling quote v1.0.33
Compiling futures-util v0.3.28
Compiling fnv v1.0.7
Compiling syn v2.0.31
Compiling itertools v0.11.0
Compiling subtle v2.5.0
Compiling pin-utils v0.1.0
Compiling rustversion v1.0.14
Compiling indexmap v1.9.3
Compiling rustix v0.38.12
Compiling num_cpus v1.16.0
Compiling parking_lot v0.12.1
Compiling signal-hook-registry v1.4.1
Compiling mio v0.8.8
Compiling socket2 v0.5.3
Compiling getrandom v0.2.10
Compiling crypto-common v0.1.6
Compiling jobserver v0.1.26
Compiling rand_core v0.6.4
Compiling block-buffer v0.10.4
Compiling httparse v1.8.0
Compiling cc v1.0.83
Compiling tinyvec_macros v0.1.1
Compiling digest v0.10.7
Compiling tinyvec v1.6.0
Compiling errno v0.3.3
Compiling bitflags v2.4.0
Compiling hashbrown v0.12.3
Compiling ppv-lite86 v0.2.17
Compiling percent-encoding v2.3.0
Compiling form_urlencoded v1.2.0
Compiling rand_chacha v0.3.1
Compiling cpufeatures v0.2.9
Compiling unicode-bidi v0.3.13
Compiling regex-syntax v0.7.5
Compiling untrusted v0.7.1
Compiling unicode-normalization v0.1.22
Compiling thiserror v1.0.48
Compiling equivalent v1.0.1
Compiling tower-service v0.3.2
Compiling heck v0.4.1
Compiling hashbrown v0.14.0
Compiling ring v0.16.20
Compiling bytes v1.5.0
Compiling prettyplease v0.2.15
Compiling futures-channel v0.3.28
Compiling idna v0.4.0
Compiling indexmap v2.0.0
Compiling rand v0.8.5
Compiling fastrand v2.0.0
Compiling home v0.5.5
Compiling regex-automata v0.3.8
Compiling async-trait v0.1.73
Compiling core-foundation-sys v0.8.4
Compiling fixedbitset v0.4.2
Compiling try-lock v0.2.4
Compiling tempfile v3.8.0
Compiling petgraph v0.6.4
Compiling want v0.3.1
Compiling url v2.4.1
Compiling which v4.4.2
Compiling axum-core v0.3.4
Compiling sha1 v0.10.5
Compiling socket2 v0.4.9
Compiling base64 v0.21.4
Compiling utf-8 v0.7.6
Compiling regex v1.9.5
Compiling ryu v1.0.15
Compiling serde_json v1.0.106
Compiling rustls v0.21.7
Compiling serde_derive v1.0.188
Compiling tokio-macros v2.1.0
Compiling tracing-attributes v0.1.26
Compiling futures-macro v0.3.28
Compiling prost-derive v0.12.0
Compiling thiserror-impl v1.0.48
Compiling pin-project-internal v1.1.3
Compiling multimap v0.8.3
Compiling data-encoding v2.4.0
Compiling httpdate v1.0.3
Compiling bitflags v1.3.2
Compiling byteorder v1.4.3
Compiling tower-layer v0.3.2
Compiling pin-project v1.1.3
Compiling tracing v0.1.37
Compiling core-foundation v0.9.3
Compiling security-framework-sys v2.9.1
Compiling prost v0.12.0
Compiling axum v0.6.20
Compiling mime v0.3.17
Compiling prost-types v0.12.0
Compiling utf8parse v0.2.1
Compiling security-framework v2.9.2
Compiling anstyle-parse v0.2.1
Compiling async-stream-impl v0.3.5
Compiling rustls-pemfile v1.0.3
Compiling inout v0.1.3
Compiling anstyle v1.0.2
Compiling colorchoice v1.0.0
Compiling matchit v0.7.2
Compiling lazy_static v1.4.0
Compiling anstyle-query v1.0.0
Compiling memchr v2.6.3
Compiling regex-syntax v0.6.29
Compiling prost-build v0.12.0
Compiling sync_wrapper v0.1.2
Compiling rustls-webpki v0.101.4
Compiling sct v0.7.0
Compiling tonic-build v0.10.0
Compiling anstream v0.5.0
Compiling sshx-core v0.2.1 (/Users/George/Develop/Rust/sshx/crates/sshx-core)
Compiling regex-automata v0.1.10
Compiling async-stream v0.3.5
Compiling rustls-native-certs v0.6.3
Compiling cipher v0.4.4
Compiling base64ct v1.6.0
Compiling clap_lex v0.5.1
Compiling serde_path_to_error v0.1.14
Compiling serde_urlencoded v0.7.1
Compiling strsim v0.10.0
Compiling tokio v1.32.0
Compiling http v0.2.9
Compiling http-body v0.4.5
Compiling tungstenite v0.20.0
Compiling overload v0.1.1
Compiling nu-ansi-term v0.46.0
Compiling clap_builder v4.4.2
Compiling password-hash v0.5.0
Compiling tokio-util v0.7.8
Compiling h2 v0.3.21
Compiling tower v0.4.13
Compiling tokio-io-timeout v1.2.0
Compiling tokio-tungstenite v0.20.0
Compiling tokio-stream v0.1.14
Compiling tokio-rustls v0.24.1
Compiling matchers v0.1.0
Compiling tracing-log v0.1.3
Compiling sharded-slab v0.1.4
Compiling clap_derive v4.4.2
Compiling blake2 v0.10.6
Compiling thread_local v1.1.7
Compiling tracing-subscriber v0.3.17
Compiling nix v0.27.1
Compiling argon2 v0.5.2
Compiling aes v0.8.3
Compiling ctr v0.9.2
Compiling close_fds v0.3.2
Compiling encoding_rs v0.8.33
Compiling ansi_term v0.12.1
Compiling clap v4.4.2
Compiling hyper v0.14.27
Compiling hyper-timeout v0.4.1
Compiling tonic v0.10.0
Compiling sshx v0.2.1 (/Users/George/Develop/Rust/sshx/crates/sshx)
Finished release [optimized] target(s) in 35.27s
将编译好的客户端可执行文件放到 /usr/local/bin
目录,并启动:
sudo mv target/release/sshx /usr/local/bin/
sshx --server https://sshx.test
sshx v0.2.1
➜ Link: https://sshx.test/s/ynl7pSGppb#MYnh4yeL3LVdTn
➜ Shell: /bin/zsh
在浏览器里打开链接后,可以看到网络延迟 4ms,用户体验又上升了一个台阶:
在内部使用,让需要远程协助的人下载你打包好的客户端并执行命令即可!
总结⌗
在过去,我多次遇到帮助他人调试 CLI 中的错误,而每个人的习惯是不同的,例如:用的屏幕、键盘等,SSHX 则避免了这些问题。
同时也避免了一些尴尬,如:
- 例如看到对方不该看的内容
- 操作中多次需要对方输入密码
有了 SSHX 以后,降低了沟通成本,提高了协作效率!
I hope this is helpful, Happy hacking…