Ssh管理工具-tssh
tsshd 是类似 mosh-server 的开源程序,主要实现 sshd 相关的功能,与 tssh 客户端使用 UDP (KCP)通讯,达到低延迟的目的。采用Go语言编写开发并在MIT协议下授权使用。trzsz-ssh (tssh) 与 tsshd 配套使用,适用于高延迟的弱网连接,切换网络、休眠与唤醒都不会掉线,让 ssh 会话永远保持。tssh 设计为 ssh 客户端的直接替代品,提供与 openssh 完全兼容的基础功能,同时实现其他有用的扩展功能,外加:
1.客户端进入休眠并且迟些再唤醒,或者暂时断开网络,ssh 会话可以保持不掉线。
2.客户端换地方接入,更换 IP 地址,任意切换网络等,ssh 会话可以保持不中断。
它支持选择或搜索 ~/.ssh/config 中配置的服务器,支持 vim 操作习惯,解决 ssh 终端的服务器管理问题。支持一次选择多台服务器,批量登录,并支持批量执行预先指定的命令,方便快速完成批量服务器操作。支持配置服务器登录密码,解决每次手工输入密码的麻烦(在自己能控制的服务器,推荐使用公私钥登录)。tssh 内置支持 trzsz (trz/tsz) 文件传输工具,一并解决了 Windows 中使用 trzsz ssh 上传速度很慢的问题。
使用方法
~/ 代表 HOME 目录。在 Windows 中,请将下文的 ~/ 替换成 C:\Users\your_name\。
在客户端生成密钥对,一般存放在 ~/.ssh/ 下:
ssh-keygen -t rsa -b 4096 生成 RSA 的,私钥 ~/.ssh/id_rsa,公钥 ~/.ssh/id_rsa.pub。
登录服务器,将公钥(即前面生成密钥对时 .pub 后缀的文件内容)追加写入服务器上的 ~/.ssh/authorized_keys 文件中。
一行代表一个客户端的公钥,注意 ~/.ssh/authorized_keys 要设置正确的权限:
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
在客户端配置好 ~/.ssh/config 文件,举例:
Host alias1
HostName 192.168.0.1
Port 22
User your_name
Host alias2
HostName 192.168.0.2
Port 22
User your_name
使用 tssh 命令登录服务器,tssh alias1 命令登录在 ~/.ssh/config 中 alias1 对应的服务器。直接执行 tssh 命令(不带参数),可以选择(搜索) ~/.ssh/config 中配置好的服务器并登录。
批量登录
目前支持在 tmux 和 Windows Terminal 中一次选择多台服务器,批量登录,并支持批量执行预先指定的命令。按下 Space、Ctrl+Space 或 Alt+Space 可以选中或取消当前服务器,若不能选中说明还不支持当前终端,请先运行 tmux。按下 Enter 或 Ctrl+P 会以分屏的方式批量登录,Ctrl+W 会打开新窗口批量登录,Ctrl+T 会打开新 tab 批量登录。
tssh 不带参数启动可以批量登录服务器,若带 -o RemoteCommand 参数启动则可以批量执行指定的命令。支持执行指定命令之后进入交互式 shell,但 Windows Terminal 不支持分号 ;,可以用 |cat&& 代替。举例:
tssh -t -o RemoteCommand='ping -c3 trzsz.github.io ; bash'
tssh -t -o RemoteCommand="ping -c3 trzsz.github.io |cat&& bash"
记住密码
为了兼容标准 ssh ,密码配置项独立放在 ~/.ssh/password 中,其他配置项依然放在 ~/.ssh/config 中。推荐使用前面密钥认证的方式,密码的安全性弱一些。如果必须要用,建议设置好 ~/.ssh/password 的权限:
chmod 700 ~/.ssh && chmod 600 ~/.ssh/password
下面 ~/.ssh/password 配置 test2 的密码是 123456,其他以 test 开头的密码是 111111:
Host test2
Password 123456
# ~/.ssh/config 和 ~/.ssh/password 是支持通配符的,tssh 会使用第一个匹配到的值。
# 这里希望 test2 使用区别于其他 test* 的密码,所以将 test* 放在了 test2 的后面。
Host test*
Password 111111
记住答案
除了私钥和密码,还有一种登录方式,英文叫 keyboard interactive ,是服务器返回一些问题,客户端提供正确的答案就能登录,很多自定义的一次性密码就是利用这种方式实现的。如果答案是固定不变的,tssh 支持 “记住答案”,也是在 ~/.ssh/password 中进行配置。大部分都是只有一个问题,只要配置 QuestionAnswer1 即可。对于有多个问题的,每个问题答案可按序号进行配置,也可以按问题的 hex 编码进行配置。使用 tssh --debug 登录,会输出问题的 hex 编码,从而知道该如何使用 hex 编码进行配置。配置举例:
Host test1
QuestionAnswer1 答案一
Host test2
QuestionAnswer1 答案一
QuestionAnswer2 答案二
QuestionAnswer3 答案三
Host test3
6e616d653a20 my_name # 其中 `6e616d653a20` 是问题 `name: ` 的 hex 编码
636f64653a20 my_code # 其中 `636f64653a20` 是问题 `code: ` 的 hex 编码
另有基于 UDP 的 ssh - tsshd
优点简介
降低延迟( 基于 QUIC / KCP )
端口转发( 与 openssh 相同,包括 ssh agent 转发和 X11 转发 )
连接迁移( 支持网络切换和掉线重连,依赖于 quic-go#234 )
如何使用
在客户端(本地电脑)上安装 tssh。
在服务端(远程机器)上安装 tsshd。
使用 tssh --udp 登录服务器。如下配置可省略 --udp 参数:
Host xxx
#!! UdpMode yes
#!! UdpPort 61000-62000
#!! TsshdPath ~/go/bin/tsshd
原理简介
tssh 在客户端扮演 ssh 的角色,tsshd 在服务端扮演 sshd 的角色。
tssh 会先作为一个 ssh 客户端正常登录到服务器上,然后在服务器上启动一个新的 tsshd 进程。tsshd 进程会随机侦听一个 61000 到 62000 之间的 UDP 端口(可通过 UdpPort 配置自定义),并将其端口和密钥通过 ssh 通道发回给 tssh 进程。登录的 ssh 连接会被关闭,然后 tssh 进程通过 UDP 与 tsshd 进程通讯。
tsshd 支持 QUIC 和 KCP 协议(默认为前者),可以命令行指定(如 -oUdpMode=KCP),或如下配置:
Host xxx
#!! UdpMode KCP
优点简介
降低延迟(基于 QUIC / KCP)
端口转发(与 openssh 相同,包括 ssh agent 转发和 X11 转发)
连接迁移(支持网络切换和掉线重连,依赖于 quic-go)
如何使用
在客户端(本地电脑)上安装 tssh。
在服务端(远程机器)上安装 tsshd。
使用 tssh --udp 登录服务器。如下配置可省略 --udp 参数(下文有详解):
Host xxx
#!! UdpMode yes
#!! UdpPort 61000-62000
#!! TsshdPath ~/go/bin/tsshd
原理简介
tssh 在客户端扮演 ssh 的角色,tsshd 在服务端扮演 sshd 的角色。
tssh 会先作为一个 ssh 客户端正常登录到服务器上,然后在服务器上启动一个新的 tsshd 进程。
tsshd 进程会随机侦听一个 61000 到 62000 之间的 UDP 端口(可通过 UdpPort 配置自定义),并将其端口和密钥通过 ssh 通道发回给 tssh 进程。登录的 ssh 连接会被关闭,然后 tssh 进程通过 UDP 与 tsshd 进程通讯。其支持 QUIC 协议和 KCP 协议(默认是 QUIC 协议),可以命令行指定(如 -oUdpMode=KCP)。
客户端 KCP/QUIC Client 和 Client Proxy 在同一台机同一个进程内,它们之间的连接不会断。
服务端 KCP/QUIC Server 和 Server Proxy 在同一台机同一个进程内,它们之间的连接不会断。
客户端较长时间没收到服务端的心跳包时,可能是因为网络变化导致原连接失效了,则由 Client Proxy 重新建一个到 Server Proxy 的连接,认证通过后就使用新连接进行通讯。在 KCP/QUIC Client 和 KCP/QUIC Server 看来,连接从来没有断开过。其UDP 模式为该软件集的一大特色。
安装方法
主流发行版本均支持从源中安装。
用 Go 直接安装(要求 go 1.21 以上)
go install github.com/trzsz/tsshd/cmd/tsshd@latest
go install github.com/trzsz/tsshd/cmd/tsshd@latest
安装后,tsshd 程序一般位于 ~/go/bin/ 目录下(Windows 一般在 C:\Users\your_name\go\bin\)。
用 Go 自己编译(要求 go 1.21 以上)
make install
git clone --depth 1 https://github.com/trzsz/tsshd.git
cd tsshd
make
make install
可从 GitHub Releases 中下载,国内可从 Gitee 发行版中下载,解压并加到 PATH 环境变量中。
安全保障
服务端 KCP/QUIC Server 只监听本机 127.0.0.1,并且只接受一个连接,在本进程的 Server Proxy 连上后,其他所有连接都会直接拒绝。
客户端 Client Proxy 只监听本机 127.0.0.1,并且只接受一个连接,在本进程的 KCP/QUIC Client 连上后,其他所有连接都会直接拒绝。
服务端 Server Proxy 只转发认证过的唯一的客户端 Client Proxy 的报文。客户端 Client Proxy 可以换 IP 地址和端口,但新的客户端 Client Proxy 认证后,服务端 Server Proxy 就只为新的客户端 Client Proxy 转发报文,忽略旧的客户端 Client Proxy 地址。
客户端 Client Proxy 首次连接或换新 IP 端口重新连接到服务端 Server Proxy 时,需要先发送认证报文( 使用 AES-GCM-256 算法加密,密钥是服务端随机生成的一次性密钥,登录时通过 ssh 通道发送给客户端 )。服务端 Server Proxy 正常解密认证报文(未被篡改)后,校验客户端 ID 符合预期,校验序列号比之前收到过的所有认证报文中的序列号都要大,则将该客户端地址标为已认证地址,同时向客户端发送认证确认报文( 使用 AES-GCM-256 算法加密 )。客户端 Client Proxy 收到服务端 Server Proxy 的认证确认报文并正常解密(未被篡改)后,校验服务端 ID 和序列号,符合预期则开始使用新地址与服务端 Server Proxy 通讯,将来自本进程 KCP/QUIC Client 的报文转发给服务端 Server Proxy,服务端 Server Proxy 再转发给本进程的 KCP/QUIC Server 服务。
客户端 KCP/QUIC Client 与服务端 KCP/QUIC Server 使用开源的 KCP / QUIC 协议,全程使用加密传输( 密钥是服务端随机生成的一次性密钥,登录时通过 ssh 通道发送给客户端 )。
要解决的问题
1.服务器太多,记不住所有别名,tssh 内置登录界面,支持搜索和选择服务器登录。
2.tssh 登录服务器后,内置支持 trzsz (trz /tsz) 工具,传文件无需另外新开窗口。
3.有时需要同时登录一批机器,tssh 支持多选并批量登录,同时支持执行预设的命令。
4.有些服务器不支持公钥登录,tssh 支持记住密码,支持自动交互,提升登录的效率。
5.在 Windows 中使用 tssh 代替 trzsz ssh,可以解决 trz 上传速度很慢的问题。
6.tssh 与 tsshd 类似于 mosh,解决了部分 mosh 的问题,例如 SSH 转发和 ProxyJump 等。
配置说明
Host xxx
#!! UdpMode Yes
#!! UdpPort 61001-61999
#!! TsshdPath ~/go/bin/tsshd
#!! UdpAliveTimeout 86400
#!! UdpHeartbeatTimeout 3
#!! UdpReconnectTimeout 15
#!! ShowNotificationOnTop yes
#!! ShowFullNotifications yes
UdpMode: No (默认为 No: tssh 工作在 TCP 模式), Yes (默认协议: QUIC), QUIC (QUIC 协议:速度更快), KCP (KCP 协议:延迟更低).
UdpPort: 指定 tsshd 监听的 UDP 端口范围,默认值为 [61001, 61999]。
TsshdPath: 指定服务器上 tsshd 二进制程序的路径,如果未配置,则在 $PATH 中查找。
UdpAliveTimeout: 如果断开连接的时间超过 UdpAliveTimeout 秒,tssh 和 tsshd 都会退出,不再支持重连。默认值为 86400 秒。
UdpHeartbeatTimeout: 如果断开连接的时间超过 UdpHeartbeatTimeout 秒,tssh 将会尝试换条路重新连到服务器。默认值为 3 秒。
UdpReconnectTimeout: 如果断开连接的时间超过 UdpReconnectTimeout 秒,tssh 将会显示失去连接的通知公告。默认值为 15 秒。
ShowNotificationOnTop: 是否在屏幕顶部显示失去连接的通知。默认为 yes,这可能会覆盖之前的一些输出。设置为 No 在光标当前行显示通知。
ShowFullNotifications: 是显示完整的通知,还是显示简短的通知。默认为 yes,这可能会输出几行通知到屏幕上。设置为 No 只输出一行通知。
登录界面
使用之前,需要配置好 ~/.ssh/config ( Windows 是 C:\Users\xxx\.ssh\config, xxx 换成用户名 )。
关于如何配置 ~/.ssh/config,请参考 openssh ( 暂不支持 Match ),或参考 tssh wiki SSH 基本配置。
直接无参数运行 tssh 命令就会打开登录界面,或者有除目标机器外的其他参数也会打开登录界面。
如果目标机器参数是 ~/.ssh/config 中别名的一部分,不能完全匹配某个别名,也会打开登录界面。
如果配置了 #!! HideHost yes,或者别名中含有 * 或 ? 通配符时,则不会显示在登录界面中。
tssh 支持很多快捷键,支持搜索,在 tmux、iTerm2 和 Windows Terminal 等中使用时支持多选。
| 操作 | 全局快捷键 | 非搜索快捷键 | 快捷键描述 |
| Confirm | Enter | 确认并登录 | |
| Quit/Exit | Ctrl+C Ctrl+Q | q Q | 取消并退出 |
| Move Prev | Ctrl+K Shift+Tab ↑ | k K | 往上移光标 |
| Move Next | Ctrl+J Tab ↓ | j J | 往下移光标 |
| Page Up | Ctrl+H Ctrl+U Ctrl+B PageUp ← | h H u U b B | 往上翻一页 |
| Page Down | Ctrl+L Ctrl+D Ctrl+F PageDown → | l L d D f F | 往下翻一页 |
| Goto Home | Home | g | 跳到第一行 |
| Goto End | End | G | 跳到最尾行 |
| EraseKeys | Ctrl+E | e E | 擦除搜索关键字 |
| TglSearch | / | 切换搜索功能 | |
| Tgl Help | ? | 切换帮助信息 | |
| TglSelect | Ctrl+X Ctrl+Space Alt+Space | Space x X | 切换选中状态 |
| SelectAll | Ctrl+A | a A | 全选当前页 |
| SelectOpp | Ctrl+O | o O | 反选当前页 |
| Open Wins | Ctrl+W | w W | 新窗口批量登录 |
| Open Tabs | Ctrl+T | t T | 新 Tab 批量登录 |
| Open Pane | Ctrl+P | p P | 分屏批量登录 |
主题风格
tssh 支持多种主题风格,在 $XDG_CONFIG_HOME/tssh/tssh.conf ( 或 ~/.tssh.conf ) 中配置 PromptThemeLayout 选用。
每种主题风格都支持自定义颜色,在 $XDG_CONFIG_HOME/tssh/tssh.conf ( 或 ~/.tssh.conf ) 中配置 PromptThemeColors,只要配置非默认的颜色即可。
另外还支持 trzsz、zmodem、批量登录、分组标签、自动交互、记住密码、记住答案、个性配置、Wayland 集成、剪贴板集成等功能。
最新版本:0.18
于2023年7月发布,目前支持在 tmux 和 Windows Terminal 中一次选择多台服务器,批量登录,并支持批量执行预先指定的命令。按下 Space、Ctrl+Space 或 Alt+Space 可以选中或取消当前服务器,若不能选中说明还不支持当前终端,请先运行 tmux。按下 Enter 或 Ctrl+P 会以分屏的方式批量登录,Ctrl+W 会打开新窗口批量登录,Ctrl+T 会打开新 tab 批量登录。
tssh 不带参数启动可以批量登录服务器,若带 -o RemoteCommand 参数启动则可以批量执行指定的命令。支持执行指定命令之后进入交互式 shell,但 Windows Terminal 不支持分号 ;,可以用 |cat&& 代替。举例:
tssh -t -o RemoteCommand='ping -c3 trzsz.github.io ; bash'
tssh -t -o RemoteCommand="ping -c3 trzsz.github.io |cat&& bash"
项目主页:https://github.com/trzsz/trzsz-ssh