tssh 是一个开源的跨平台的 SSH Client ,它的优点有:

  1. 支持密码登录,支持自动输入 TOTP 验证码。
  2. 支持 trz 和 tsz 上传下载文件,同时支持 lrzsz 上传下载文件(无须终端软件如 iTerm 等支持)
  3. 支持使用 shell 脚本生成 QuestionAnswer 自动输入

安装

macOS

1
2
3
4
# 安装
git clone https://github.com/iuxt/trzsz-ssh.git
cd trzsz-ssh
./build.sh

使用 tssh 替代 ssh 命令

Windows

使用 windows 版 tssh.exe

lrzsz 可以使用 Release v0.12.21rc · trzsz/lrzsz-win32 · GitHub,放到 PATH 环境变量路径下,不清楚的也可以直接扔进 C:\Windows 目录下。
直接 github 上下载 tssh.exe 所在路径放到 PATH 环境变量中即可。rz 或 sz 的时候打开的是资源管理器 explorer.exe

在 WSL2 中使用

安装 Linux 版 tssh,并安装 zenity 包,文件管理器是 Linux 桌面版文件管理器。

1
2
# 解决 rz 或 sz 无法弹出文件管理器的问题。
sudo apt install libgles2 zenity fonts-wqy-microhei -y

Linux

同 Windows 的 WSL2

常用 tssh 命令

1
2
3
4
5
6
7
8
9
### 自动在服务器上安装 lrzsz
tssh --install-trzsz root@x.x.x.x

### 交互式添加机器
tssh --new-host

### 指定用户名, ssh 用户名带 `@` 符号的时候,使用 tssh 会解析错误(ssh 无问题)此时可以指定用户名的方式来使用。
# --zmodem 是开启 zmodem 支持,可以使用 rz 或 sz 命令。
tssh --zmodem -l 'a@qq.com' 1.1.1.1 -p 2222

配置文件

连接配置文件

除了使用 tssh 命令的方法外,还可以将服务器信息配置到 ~/.ssh/config(类似于 openssh),为了兼容 openssh,可以将 tssh 独有的配置前加上 #!! , 后续直接使用 tssh 命令就可以进行机器选择。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 使用 ssh-key 免密连接
Host orange-pi
Hostname 1.1.1.1
HostKeyAlgorithms +ssh-rsa
PubkeyAcceptedKeyTypes +ssh-rsa
User orangepi
Port 22
IdentityFile ~/.ssh/id_rsa
IdentitiesOnly yes

# 使用密码连接
Host ubuntu
Hostname 1.1.1.1
User root
Port 22
EnableZmodem Yes
encPassword fe7219e2eb0c10aa6a0ea3c35307334e9810fd0cb042a05804dcd34b52125e088d3af3
# Password 123456

上面的 encPassword 可以通过 tssh --enc-secret 来生成,也可以使用 Password 明文密码 的方式。

使用方法

直接执行 tssh 就会有一个终端组成的图形界面
image.png

上面也可以使用 tssh test-ubuntu 来快速连接

支持 zmodem(可用于取代 lrzsz)

配置

新版 trzsz 内置支持 lrzsz 的功能,使用方法:

1
tssh --zmodem root@x.x.x.x -p 22

或者在 ~/.ssh/config 里面配置

1
2
Host *
EnableZmodem Yes

使用

然后在终端里就可以执行 rz 和 sz 命令了 (不需要修改终端的配置,比如 iTerm2 配置 triggers),并且支持上传速度和上传大小显示。

image.png

高级玩法

自动输入两步验证码

比如一个堡垒机登录需要输入 TOTP 两步验证码:
image.png|590

那么可以使用配置

1
2
3
4
5
6
7
8
9
10
11
Host 两步验证码
Hostname 10.123.1.1
HostKeyAlgorithms +ssh-rsa
PubkeyAcceptedKeyTypes +ssh-rsa
User username
Port 22
IdentitiesOnly no
Password mypassword
TotpSecret1 xxxxxxx
# 可以通过脚本来获取,脚本会输出6位数字到标准输出
# OtpCommand1 C:\Users\aaa\tools\堡垒机.bat

密码是正确的,但是无法登录

有可能你看到的密码并不是密码,实际使用的是 SSH 的 keyboard-interactive(键盘交互)认证,可以添加 --debug 来查看详情

image.png|809

所以配置文件里面应该配置,而不是配置 password

1
2
3
4
5
Host 测试节点
HostName 1.1.1.1
Port 2222
User xxxxx
QuestionAnswer1 xxxx

这里的读取顺序为:

配置项:按问题文本匹配 说明
enc50617373776f72643a20 答案的加密值。解密后直接作为答案。
50617373776f72643a20Command 执行配置中的命令,命令的标准输出直接作为答案,例如 python3 totp.py。
50617373776f72643a20 配置值直接作为答案。
enctotp50617373776f72643a20 TOTP seed 的加密值。解密后,用 seed 自动生成 6 位验证码作为答案。
totp50617373776f72643a20Command 执行配置中的命令,命令输出应是 TOTP seed;tssh 再用它生成验证码。
totp50617373776f72643a20 配置值是 TOTP seed,tssh 自动生成 6 位验证码作为答案。
encotp50617373776f72643a20 生成答案的命令的加密值。解密得到命令,再执行命令,其标准输出作为答案。
otp50617373776f72643a20Command 执行配置中的命令,其标准输出应是另一条命令;tssh 再执行输出的命令,最终标准输出作为答案。
otp50617373776f72643a20 配置值是生成答案的命令,例如 python3 totp.py,执行后的标准输出作为答案。
配置项:匹配第一个问题 说明
encQuestionAnswer1 答案的加密值。解密后直接作为答案。
QuestionAnswer1Command 执行配置中的命令,标准输出直接作为答案。
QuestionAnswer1 配置值直接作为答案。
encTotpSecret1 TOTP seed 的加密值。解密后生成验证码作为答案。
TotpSecret1Command 执行配置中的命令,标准输出应是 TOTP seed,随后生成验证码。
TotpSecret1 配置值是 TOTP seed,自动生成验证码作为答案。
encOtpCommand1 生成答案的命令的加密值。解密后执行命令,标准输出作为答案。
OtpCommand1Command 执行配置中的命令,标准输出应是另一条命令;执行第二条命令后的标准输出作为答案。
OtpCommand1 配置值是生成答案的命令,执行后的标准输出作为答案。

注意:

所有 Command 的配置,都支持替换

配置项 支持的参数替换 命令输出的用途
PasswordCommand %%、%h、%n、%p、%r 密码
PassphraseCommand 同上 私钥口令
QuestionAnswerNCommand 同上 问题答案
HEXCommand 同上 问题答案
TotpSecretNCommand 同上 TOTP seed
totpHEXCommand 同上 TOTP seed
OtpCommandNCommand 同上 生成答案的另一条命令
otpHEXCommand 同上 生成答案的另一条命令
OtpCommandN 独立参数 %q 执行后输出问题答案
otpHEX 独立参数 %q 执行后输出问题答案

参数含义:

占位符 当前实现中的含义
%% 字面量 %
%h 实际目标主机名或 IP
%n 命令行中指定的原始目标主机名或别名,例如 测试节点
%p 目标 SSH 端口,例如 2222
%r 远端登录用户名
%l 本机主机名,使用 os.Hostname() 返回值
%L 本机短主机名,截取第一个 . 之前的部分
%j ProxyJump 链中的最后一个跳板配置字符串;无跳板时为空
%k HostKeyAlias 的值;未配置时使用原始目标别名
%C 本机主机名、目标主机、端口、远端用户名等拼接后的 SHA-1 十六进制摘要;允许 %j 的场景还会加入最后一个跳板
%q OTP 命令收到的问题文本;必须作为独立参数使用

比如

1
2
3
4
5
# 按主机、端口、用户获取密码
PasswordCommand python3 get_password.py %h %p %r

# 根据服务器提问生成答案
OtpCommand1 python3 get_answer.py %q