ttyd配合lrzsz/trzsz实现文件传输

安装ttyd

因为管理服务器需要登录堡垒机需要双因子认证,麻烦得很这才想到了用ttyd
我的安装是直接下载github上的文件,放在了系统环境变量PATH中的目录里面:

1
2
curl -L -o /usr/local/bin/ttyd https://github.com/tsl0922/ttyd/releases/download/1.7.7/ttyd.x86_64
chmod +x /usr/local/bin/ttyd

编辑配置文件

看官方介绍能支持不少功能:

1
2
3
4
5
6
7
8
Built on top of libuv and WebGL2 for speed
Fully-featured terminal with CJK and IME support
ZMODEM (lrzsz) / trzsz file transfer support
Sixel image output support (img2sixel / lsix)
SSL support based on OpenSSL / Mbed TLS
Run any custom command with options
Basic authentication support and many other custom options
Cross platform: macOS, Linux, FreeBSD/OpenBSD, OpenWrt, Windows

我主要用到的是文件传输功能,参考wiki:
https://github.com/tsl0922/ttyd/wiki/Example-Usage
https://github.com/tsl0922/ttyd/wiki/Client-Options

1
2
enable ZMODEM / lrzsz file transfer support: ttyd -t enableZmodem=true bash
enable trzsz file transfer support: ttyd -t enableTrzsz=true bash

下面来编写一个systemd service让ttyd自启动:
编辑/etc/systemd/system/ttyd.service
enableTrzsz=true 启用这个是因为lrzsz上传超过100M终端会乱码;
enableZmodem=true 这个是启用lrzsz,这个我测试100M以内的文件能够正常工作
-c 是配置简单的认证用户和密码;
-W 是启用可写,如果不加上这个参数终端是没法输入的;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Unit]
Description=ttyd - Share your terminal over the web
After=network.target

[Service]
ExecStart=/usr/local/bin/ttyd -t enableTrzsz=true -t enableZmodem=true -c admin:xxxx@ -W bash
Restart=always
User=root
Group=root
Environment=TERM=xterm-256color
WorkingDirectory=/root
StandardOutput=null
StandardError=journal

[Install]
WantedBy=multi-user.target

重新读取所有daemon:

1
systemctl daemon-reload

加入开机自启动:

1
systemctl enable ttyd

启动ttyd:

1
systemctl start ttyd

安装lrzsz:

1
dnf install lrzsz

安装trzsz:

1
pip install trzsz

然后就能通过浏览器访问了:localhost:7681
不过我这边为了能够跳过堡垒机直接访问终端,我还在服务器上部署了一个nginx,然后通过nginx反代了ttyd服务;我的配置如下:

1
2
3
4
5
6
7
8
9
10
11
location /ttyd/ {
proxy_pass http://ttyd:7681/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;

# 防止 WebSocket 子路径混淆
rewrite /ttyd/(.*) /$1 break;
}