简单来说,就是和 lrzsz 一样的原理,原理上可以绕过堡垒机完成网络的打通,比如可以用于分享本机的互联网给生产机器。只是说 lrzsz 只能传输文件,Termtunnel 除了传输文件,还可以做端口转发。
目前使用起来还可以。推荐有需要的朋友尝试一下看看。
介于原型玩具和正式发布之间的开发状态,有 bug 正常,轻拍。如果有用的话求个 star ,多谢。
https://github.com/beordle/termtunnel
1
lj0014 2022-05-02 07:43:25 +08:00 via iPhone
有意思
|
2
aru 2022-05-03 11:11:20 +08:00
有意思啊,这个看样子能用
|
3
Chipmunker 2022-05-03 23:40:58 +08:00
好像不支持 Windows 啊。
|
4
beordle OP 通过 WSL 的话目前就可以运行了,只是对 windows 版本有要求。编译成普通 exe 的话,需要适配到 cygwin ,短期内有空的话会增加一下。
|
5
beordle OP |
6
frinstioAKL 2022-05-05 11:45:35 +08:00
老哥这个实在是太猛了, 内网的机器本来没法连接软件源, 这下一下子打通了....
|
7
frinstioAKL 2022-05-05 11:49:44 +08:00
有点好奇, 这样做从技术上是不是其实就是普通的 zModem, 和 rzsz 并无本质差异, 所以从技术上看是没有违反公司安全规范的, 公司 IT 也很难去鉴定. 但是从行为上看, 绕过了跳板机就算违规了吧
|
8
beordle OP @frinstioAKL 怎么讲呢,咱们看屏幕就是在下行,敲键盘就是在上行,这个双向通信的存在不会变。毕竟使用 pty 操作 ssh ,和用 screen tmux 操作 ssh 没有任何区别,只不过这个应用会擅自帮你敲键盘,帮你解读屏幕内容自动化了而已。这个通信内容从你手动装 rpm 包下载 rz 上去通过协议转换变成了能让 yum 识别的内容,从而提高你的效率。区别在于通信本身是否会被坏人利用,矛盾的集中点在于最终提供的 socket 本身太标准,因此容易被坏人利用。毕竟这个通道的出现是你的行为导致的,大部分公司安全侧如果真的评估我想应该都属于违规。自身安全评估,我只能说 at your own risk ,为了公司安全着想的角度,临时静态端口映射的话,一般来说没什么问题。
不过这个场景只是其中之一,也有其他场景可以用。比如 lrzsz 莫名奇妙在 kubectl 中不能用的情况等等,程序的抗干扰能力要比 rzsz 强很多。 |
9
frinstioAKL 2022-05-05 13:47:35 +08:00
@beordle 感谢楼主的耐心回复, 和我预想的一样. 这个工具太有用了, 给楼主点赞
|
10
raykle 2022-05-06 00:25:33 +08:00
看不懂,但感觉很强!已 star
|
11
ThirdFlame 2022-05-06 18:12:41 +08:00
我能否这样理解,就是能在 remote 主机上开一个 socks5 代理,流量能通过本地主机出去。
比如某台服务器不能上外网,我的主机能上外网,而且我能直接 ssh 服务器。 |
12
lw3088 2022-05-06 18:23:03 +08:00
不明觉厉 先 star
|
13
des 2022-05-06 18:27:28 +08:00 via iPhone
tmux 下能用吗?
|
14
beordle OP @ThirdFlame 是的,支持默认的 openssh 所不包含的监听在远程,连接到本地模式(动态 ssh -R )。
当然也支持类似于 ssh -D ssh -R ssh -L 的模式 但主要是为了解决 ssh 自带的功能在这种情况下并不好用或者不能用的情况。比如堡垒机。比如非常非常多跳的 ssh ,又或者是 telnet 出来的 shell 。 |
15
beordle OP @des 不管 tmux 在哪一跳都可以使用的(和绝大多数高级终端都可以配合使用),只是由于 tmux 的实现原因,速度将受限,上行稍微正常,下行大约只有 10+ KB/s ,修改几行 tmux 的源码可以解决问题。但这样修改的其它副作用存疑..所以我不推荐使用本程序解决日常的 tmux 问题。社区之前有人做的 tlrzsz ,没有研究过,但可能是一个更好的选择。
|
16
billlee 2022-05-06 18:58:56 +08:00 via Android
重新发明 slirp?
|
17
beordle OP @billlee slirp 之前在 qemu 中遇到过。这个程序和 slirp 的目的还是完全不同的,但也有类似的目的,因此其实内置了 lwip tcpip 协议栈,若更换 slirp 也是可以的。
|
18
abbottcn 2022-05-06 20:08:15 +08:00
@beordle 外行问一下, 代理模式, 能给个示例吗?
比如网络互联存在如下状态: Internet <----> hostA <----private LAN----> hostB 显然 hostB 无法直接访问互联网. 借用 termtunnel, 如何让 hostB 上的 yum 工作呢? 如有打扰, 请见谅. |
19
beordle OP @abbottcn 如果 private LAN 不复杂这个实际上你可以直接使用 ssh
``` host_a$ ssh -R 8000 [email protected] host_b$ curl --socks5 127.0.0.1:8000 bing.com -v #验证 ``` 在 /etc/yum.conf 增加 proxy=socks5://127.0.0.1:8000 (原来源于网络) 如果使用 termtunnel 则是 ``` host_a$ termtunnel ssh [email protected] host_x$# 过程不重要 host_y$# 过程不重要 host_b$ termtunnel -a termtunnel >> remote 127.0.0.1 8000 127.0.0.1 0 ``` 然后再开启一个窗口 ``` host_a$ ssh [email protected] ... host_b$ curl --socks5 127.0.0.1:8000 bing.com -v #验证 ``` 在 /etc/yum.conf 增加 proxy=socks5://127.0.0.1:8000 (来源于网络) |
20
abbottcn 2022-05-06 20:34:01 +08:00 via iPhone
@beordle 多谢大佬指点,外行不胜感激。
之前用 brook ,可以非常方便的开启代理,socket http 均可……某个版本之后,居然无法使用了。 你说的对,网络不复杂的话,ssh tunnel 就搞定了……只是对外行而言,太极了…… 再次感谢你的回复。 |
21
beordle OP @abbottcn 用 termtunnel 试试吧,这可能也是一种比较好的应用场景,我看下怎么持续优化“外行”体验。毕竟优势在于中间如果很多跳的话,是可以屏蔽复杂度的。就像这个需求不管你中间网络是什么样的,你就保持正常的操作,最终你只要能在最后的主机中的 termtunnel 控制台中敲入 remote 127.0.0.1 8000 127.0.0.1 0 就可以了。
|
22
woncode 2022-05-07 02:49:06 +08:00 via Android
好作品,start 等正式版
|
23
saucerman8 2022-05-07 12:54:46 +08:00
感觉这个软件的思路可以无视所有的堡垒机,跳板机,对安全限制做到了本质打击呀,好想法
|
24
beordle OP 思路不难想,xx over xx 的东西其实一直都有,但如果真的要通用实际上也不可能。部分公司是瘦客户端,和远程桌面,这种情况就很难有好办法。还有 web js 客户端,这种情况也需要另外实现一个 webdriver 。
|
25
bojue 2022-05-07 22:19:52 +08:00
虽然用不到,但是大为震惊,已经 star
|
26
hankai17 2022-05-07 23:12:51 +08:00
提几个底层的问题
作者底层用的是 workflow 请问用的是 ET 模式吗? 是否支持多线程? 问一下 tunnel 设计 tunnel 是如何处理关闭的? |
28
beordle OP |
30
LonnyWong 2022-05-08 00:16:05 +08:00
@beordle
很强大,已 star 。 你说的 tltzsz 是指 trzsz ? https://github.com/trzsz/trzsz Termtunnel 进程拉起 ssh 子进程,就可以控制 ssh 进程的输入和输出,通过这个输入和输出就可以和远程服务器上的 Termtunnel 进程通讯,从而实现文件传输和隧道转发。不知我有没有理解错? https://github.com/trzsz/trzsz 是我写的,区别是我没有用一个本地的 trzsz 进程来拉起 ssh 子进程,而是利用 iTerm2 的 coprocess 功能,当服务器上的 trzsz 输出一个特定的字符串,iTerm2 就会拉起本地的 trzsz 进程,本地 trzsz 进程和远程 trzsz 进程是通过 iTerm2 转发输入和输出来实现通讯的。本质上和 Termtunnel 是差不多的。 trzsz 要求终端支持才能使用,我用 js 写了个组件 https://github.com/trzsz/trzsz.js ,让基于 electron 开发的终端 ( electerm 和 tabby )也同样支持了 trzsz 。trzsz.js 还支持在浏览器中使用,webshell 可很方便地集成 trzsz ,实现上传和下载文件。 trzsz 对 tmux 的支持是挺好的,并且速度挺快的,进度条功能也不错。iTerm2 支持与 tmux -CC 无缝集成,trzsz 也支持这种模式。 当 tmux 运行在本地,或者运行在中间的跳板机时,trzsz 目前还不能很好地支持。原因是远程服务器输出大量数据时,本地或中间的 tmux 会吃掉,tmux 只输出最后一屏的内容,导致文件传输不完整。楼主没有遇到这个问题,是因为传输速率慢,没有触发 tmux 吃掉的情况? 可以多多交流,一起为开源做点贡献。 |
31
LonnyWong 2022-05-08 00:32:03 +08:00 via iPhone
@beordle 刚回复完,然后看到 lwIP ,原来可以通过流控和重传来解决 tmux 丢包的问题。太强了!
|
32
beordle OP @LonnyWong 哈哈哈,实际上我基于 item2 实现过一个简单的版本,但是感觉不是很满意,主要是因为 item2 只能在 mac 上用,我也没有精力实现多个。我想实现一个从任何地方都能用的版本。主要是实现 frame 一层,不过这一层实际上如果被偶尔翻转(不是 ssh 这种 tcp 的,比如 rlogin 到喘口)就不靠谱了,这个其实好解决,我正好用 lwip 的 checksum 解决。另外还有一就是被高级重担吞的情况,因为 tmux 等实现了一个完整的终端模拟器,知道哪些地方屏幕刷新了多次没用就扔了,所以为了过 tmux (其实主要是为了对付一众基于 tmux 或者类似软件跳板机),我实际上实现了两层,有一个解析终端转移码的状态机,只提取绿色字体和绿色背景的内容。这样的话就知道有价值的信息,避免 tmux 本身的 bar 输出干扰。然后一定要实现的是慢启动,因为实际上我们不知道中间节点到底存不存在 tmux (有可能不存在丢包),因为要用最小流量试探,慢慢试探到可行的流量大小来。如果直接无脑写很多数据,到达对端的概率可能不足 0.1%。lwip 是支持慢启动的。实际上如果只用 lwip ,应该也行。不过我的状态机也不太可能是负优化就是了。
如果你的 tmux 可以被替换,事实上可以使用这个代码解决 tmux 会扔内容的问题。不过我的场景不能如此假设,就是了。 ```index c9c61086..b3333020 100644 --- a/screen-write.c +++ b/screen-write.c @@ -1645,7 +1645,7 @@ screen_write_collect_add(struct screen_write_ctx *ctx, * a plain character is encountered. */ - collect = 1; + collect = 0; if (gc->data.width != 1 || gc->data.size != 1 || *gc->data.data >= 0x7f) collect = 0; else if (gc->attr & GRID_ATTR_CHARSET) @@ -1819,7 +1819,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) } /* Write to the screen. */ - if (!skip) { + if (1 || !skip) { if (selected) { screen_select_cell(s, &tmp_gc, gc); ttyctx.cell = &tmp_gc; diff --git a/tty.c b/tty.c index bcbccca6..10bd56da 100644 --- a/tty.c +++ b/tty.c @@ -196,6 +196,7 @@ tty_timer_callback(__unused int fd, __unused short events, void *data) static int tty_block_maybe(struct tty *tty) { + return 0; struct client *c = tty->client; size_t size = EVBUFFER_LENGTH(tty->out); struct timeval tv = { .tv_usec = TTY_BLOCK_INTERVAL }; ``` |
33
ericls 2022-05-08 07:21:15 +08:00 via iPhone
思路有意思 implementation 还没看 但是提供的 API 很 intuitive 👍
|
34
LonnyWong 2022-05-08 07:24:51 +08:00 via iPhone
@beordle 太强了,建议你为 tmux 提个 PR 。加个启动参数,或.tmux.conf 配置项,默认不启用,对于有需要的自行启用就好。
|
37
lamCJ 2022-05-09 19:17:36 +08:00 via Android
如果内网网络做了 IP/域名白名单,能 bypass 吗
|
38
beordle OP 不能,只能以某个主机(对端)的身份去发起请求。不可能超出这个范畴。当然你也可以让他们一群机器都通过你的主机连到互联网…配合..frp..?
|
39
buubiu 2022-05-09 20:03:02 +08:00
star 了
|
41
LonnyWong 2022-05-10 06:44:10 +08:00 via iPhone
@diaosi 你可以参考 https://github.com/trzsz/trzsz.js/tree/main/examples/addon 这个代码自己建一个,要自己加一下登录鉴权的功能。
|
42
qbmiller 2022-05-10 09:43:00 +08:00 via Android
膜拜
|
43
littlewing 2022-05-10 21:26:34 +08:00
看到 C 写的先赞一个
|
44
Zoyo94 2022-05-12 16:22:46 +08:00
我目前用的是 autossh 跳板机 ssh -N -f -D 端口转发 。
|
45
LonnyWong 2022-05-13 09:11:56 +08:00 via iPhone
@Chipmunker 你在 windows 用的是什么终端?是在 cmd 或 powershell 中运行 ssh 登录到远程的吗?
我想,需要在某处运行楼主的软件,将 ssh 进程包起来,才能使用的。 |
46
LonnyWong 2022-05-13 09:13:54 +08:00 via iPhone
@beordle 在 windows 中运行时,你的 pty 是怎么实现的?好像没找到 windows 相关的代码。
|
49
LonnyWong 2022-05-13 16:33:00 +08:00 via iPhone
@beordle 运行的时候是要在 cygwin 中,还是可以在 cmd 中(只要安装了 cygwin )?
|
51
nicevar 2022-05-13 21:03:26 +08:00
很强,好东西,用来开发调试很方便
|
52
maskerTUI 2022-05-27 20:20:12 +08:00
改天试试
|