V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
beordle
V2EX  ›  分享创造

做了一个隧道软件,叫做 Termtunnel,邀请大家体验

  •  7
     
  •   beordle ·
    beordle · 2022-05-01 21:46:16 +08:00 · 14375 次点击
    这是一个创建于 697 天前的主题,其中的信息可能已经有所发展或是发生改变。

    简单来说,就是和 lrzsz 一样的原理,原理上可以绕过堡垒机完成网络的打通,比如可以用于分享本机的互联网给生产机器。只是说 lrzsz 只能传输文件,Termtunnel 除了传输文件,还可以做端口转发。

    目前使用起来还可以。推荐有需要的朋友尝试一下看看。

    介于原型玩具和正式发布之间的开发状态,有 bug 正常,轻拍。如果有用的话求个 star ,多谢。

    https://github.com/beordle/termtunnel

    • 传输文件功能属于赠送,速度上肯定没有 lrzsz 高的,不过好处就是可以 bypass 中间节点的 tmux (但是速度非常慢)
    第 1 条附言  ·  2022-05-03 14:22:52 +08:00
    解释一下思路:有的情况下我们只能选择使用 rz,sz 上传下载文件,其余的功能都无法使用或者性价比上不可行。那么大家有没有想过,如果我们可以自动化的 rz 一个 ip 包,sz 一个 ip 包,是否就可以实现 tcp 了呢?答案是肯定的。

    只要本地机器最终能 ssh (或者其他 console 手段)到的任意受控(可执行自定义二进制代码,但不需要 root )环境,不管多少跳,都可以实现隧道而无需中间节点的支持。因为是基于字符终端实现的通信。
    第 2 条附言  ·  2022-05-04 17:03:35 +08:00
    已增加对 Windows 的支持,默认提供的安装包中提供了 termtunnel 以及 ssh ,可以在 cmd 下运行。(未经严格测试)
    52 条回复    2022-05-27 20:20:12 +08:00
    lj0014
        1
    lj0014  
       2022-05-02 07:43:25 +08:00 via iPhone
    有意思
    aru
        2
    aru  
       2022-05-03 11:11:20 +08:00
    有意思啊,这个看样子能用
    Chipmunker
        3
    Chipmunker  
       2022-05-03 23:40:58 +08:00
    好像不支持 Windows 啊。
    beordle
        4
    beordle  
    OP
       2022-05-04 13:36:36 +08:00 via iPhone
    通过 WSL 的话目前就可以运行了,只是对 windows 版本有要求。编译成普通 exe 的话,需要适配到 cygwin ,短期内有空的话会增加一下。
    beordle
        5
    beordle  
    OP
       2022-05-04 13:37:18 +08:00 via iPhone
    frinstioAKL
        6
    frinstioAKL  
       2022-05-05 11:45:35 +08:00
    老哥这个实在是太猛了, 内网的机器本来没法连接软件源, 这下一下子打通了....
    frinstioAKL
        7
    frinstioAKL  
       2022-05-05 11:49:44 +08:00
    有点好奇, 这样做从技术上是不是其实就是普通的 zModem, 和 rzsz 并无本质差异, 所以从技术上看是没有违反公司安全规范的, 公司 IT 也很难去鉴定. 但是从行为上看, 绕过了跳板机就算违规了吧
    beordle
        8
    beordle  
    OP
       2022-05-05 13:36:28 +08:00 via iPhone   ❤️ 1
    @frinstioAKL 怎么讲呢,咱们看屏幕就是在下行,敲键盘就是在上行,这个双向通信的存在不会变。毕竟使用 pty 操作 ssh ,和用 screen tmux 操作 ssh 没有任何区别,只不过这个应用会擅自帮你敲键盘,帮你解读屏幕内容自动化了而已。这个通信内容从你手动装 rpm 包下载 rz 上去通过协议转换变成了能让 yum 识别的内容,从而提高你的效率。区别在于通信本身是否会被坏人利用,矛盾的集中点在于最终提供的 socket 本身太标准,因此容易被坏人利用。毕竟这个通道的出现是你的行为导致的,大部分公司安全侧如果真的评估我想应该都属于违规。自身安全评估,我只能说 at your own risk ,为了公司安全着想的角度,临时静态端口映射的话,一般来说没什么问题。

    不过这个场景只是其中之一,也有其他场景可以用。比如 lrzsz 莫名奇妙在 kubectl 中不能用的情况等等,程序的抗干扰能力要比 rzsz 强很多。
    frinstioAKL
        9
    frinstioAKL  
       2022-05-05 13:47:35 +08:00
    @beordle 感谢楼主的耐心回复, 和我预想的一样. 这个工具太有用了, 给楼主点赞
    raykle
        10
    raykle  
       2022-05-06 00:25:33 +08:00
    看不懂,但感觉很强!已 star
    ThirdFlame
        11
    ThirdFlame  
       2022-05-06 18:12:41 +08:00
    我能否这样理解,就是能在 remote 主机上开一个 socks5 代理,流量能通过本地主机出去。

    比如某台服务器不能上外网,我的主机能上外网,而且我能直接 ssh 服务器。
    lw3088
        12
    lw3088  
       2022-05-06 18:23:03 +08:00
    不明觉厉 先 star
    des
        13
    des  
       2022-05-06 18:27:28 +08:00 via iPhone
    tmux 下能用吗?
    beordle
        14
    beordle  
    OP
       2022-05-06 18:29:21 +08:00
    @ThirdFlame 是的,支持默认的 openssh 所不包含的监听在远程,连接到本地模式(动态 ssh -R )。

    当然也支持类似于 ssh -D ssh -R ssh -L 的模式

    但主要是为了解决 ssh 自带的功能在这种情况下并不好用或者不能用的情况。比如堡垒机。比如非常非常多跳的 ssh ,又或者是 telnet 出来的 shell 。
    beordle
        15
    beordle  
    OP
       2022-05-06 18:38:32 +08:00
    @des 不管 tmux 在哪一跳都可以使用的(和绝大多数高级终端都可以配合使用),只是由于 tmux 的实现原因,速度将受限,上行稍微正常,下行大约只有 10+ KB/s ,修改几行 tmux 的源码可以解决问题。但这样修改的其它副作用存疑..所以我不推荐使用本程序解决日常的 tmux 问题。社区之前有人做的 tlrzsz ,没有研究过,但可能是一个更好的选择。
    billlee
        16
    billlee  
       2022-05-06 18:58:56 +08:00 via Android
    重新发明 slirp?
    beordle
        17
    beordle  
    OP
       2022-05-06 19:22:41 +08:00 via iPhone
    @billlee slirp 之前在 qemu 中遇到过。这个程序和 slirp 的目的还是完全不同的,但也有类似的目的,因此其实内置了 lwip tcpip 协议栈,若更换 slirp 也是可以的。
    abbottcn
        18
    abbottcn  
       2022-05-06 20:08:15 +08:00
    @beordle 外行问一下, 代理模式, 能给个示例吗?
    比如网络互联存在如下状态:
    Internet <----> hostA <----private LAN----> hostB
    显然 hostB 无法直接访问互联网.
    借用 termtunnel, 如何让 hostB 上的 yum 工作呢? 如有打扰, 请见谅.
    beordle
        19
    beordle  
    OP
       2022-05-06 20:29:09 +08:00
    @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 (来源于网络)
    abbottcn
        20
    abbottcn  
       2022-05-06 20:34:01 +08:00 via iPhone
    @beordle 多谢大佬指点,外行不胜感激。
    之前用 brook ,可以非常方便的开启代理,socket http 均可……某个版本之后,居然无法使用了。

    你说的对,网络不复杂的话,ssh tunnel 就搞定了……只是对外行而言,太极了……

    再次感谢你的回复。
    beordle
        21
    beordle  
    OP
       2022-05-06 20:47:22 +08:00
    @abbottcn 用 termtunnel 试试吧,这可能也是一种比较好的应用场景,我看下怎么持续优化“外行”体验。毕竟优势在于中间如果很多跳的话,是可以屏蔽复杂度的。就像这个需求不管你中间网络是什么样的,你就保持正常的操作,最终你只要能在最后的主机中的 termtunnel 控制台中敲入 remote 127.0.0.1 8000 127.0.0.1 0 就可以了。
    woncode
        22
    woncode  
       2022-05-07 02:49:06 +08:00 via Android
    好作品,start 等正式版
    saucerman8
        23
    saucerman8  
       2022-05-07 12:54:46 +08:00
    感觉这个软件的思路可以无视所有的堡垒机,跳板机,对安全限制做到了本质打击呀,好想法
    beordle
        24
    beordle  
    OP
       2022-05-07 14:32:50 +08:00 via iPhone
    思路不难想,xx over xx 的东西其实一直都有,但如果真的要通用实际上也不可能。部分公司是瘦客户端,和远程桌面,这种情况就很难有好办法。还有 web js 客户端,这种情况也需要另外实现一个 webdriver 。
    bojue
        25
    bojue  
       2022-05-07 22:19:52 +08:00
    虽然用不到,但是大为震惊,已经 star
    hankai17
        26
    hankai17  
       2022-05-07 23:12:51 +08:00
    提几个底层的问题
    作者底层用的是 workflow 请问用的是 ET 模式吗? 是否支持多线程?
    问一下 tunnel 设计 tunnel 是如何处理关闭的?
    quzard
        27
    quzard  
       2022-05-07 23:16:58 +08:00 via Android
    @beordle 能支持 http 代理吗,看现在只有 socks
    beordle
        28
    beordle  
    OP
       2022-05-07 23:52:30 +08:00 via iPhone
    @hankai17 workflow 是什么呢,不太了解这个。

    这个应用没有你想象的底层。使用了 libuv ,并非自写的事件循环,它是支持多线程的。一开始我自己测试的 demo 用的是自己写的 LTepoll ,我自己基本没有用过 et 。

    如果要支持 tmux 这种会在中间丢包的节点,需要实现流量控制和重传,因此引入了 lwip ,将 7 层抽象成 4 层是 lwip 自带的功能。tunnel 关闭我不太清楚你指的是什么,额我就说下我认为的吧。tunnel 依赖两端主动关闭,各关各的,支持半开 shutdown 。

    @quzard 也支持简单的端口转发,sock5 很多时候是满足不了需求吗?
    quzard
        29
    quzard  
       2022-05-08 00:06:33 +08:00 via Android   ❤️ 1
    @beordle 有些不支持 socks5 比如 wget
    LonnyWong
        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 吃掉的情况?

    可以多多交流,一起为开源做点贡献。
    LonnyWong
        31
    LonnyWong  
       2022-05-08 00:32:03 +08:00 via iPhone
    @beordle 刚回复完,然后看到 lwIP ,原来可以通过流控和重传来解决 tmux 丢包的问题。太强了!
    beordle
        32
    beordle  
    OP
       2022-05-08 00:55:09 +08:00
    @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 };

    ```
    ericls
        33
    ericls  
       2022-05-08 07:21:15 +08:00 via iPhone
    思路有意思 implementation 还没看 但是提供的 API 很 intuitive 👍
    LonnyWong
        34
    LonnyWong  
       2022-05-08 07:24:51 +08:00 via iPhone
    @beordle 太强了,建议你为 tmux 提个 PR 。加个启动参数,或.tmux.conf 配置项,默认不启用,对于有需要的自行启用就好。
    beordle
        35
    beordle  
    OP
       2022-05-08 19:50:39 +08:00
    @quzard 1.5.1 增加了 http 协议支持,和 socks5 同端口。
    quzard
        36
    quzard  
       2022-05-08 21:39:14 +08:00 via Android
    @beordle 高效率👍
    lamCJ
        37
    lamCJ  
       2022-05-09 19:17:36 +08:00 via Android
    如果内网网络做了 IP/域名白名单,能 bypass 吗
    beordle
        38
    beordle  
    OP
       2022-05-09 19:27:05 +08:00 via iPhone
    不能,只能以某个主机(对端)的身份去发起请求。不可能超出这个范畴。当然你也可以让他们一群机器都通过你的主机连到互联网…配合..frp..?
    buubiu
        39
    buubiu  
       2022-05-09 20:03:02 +08:00
    star 了
    diaosi
        40
    diaosi  
       2022-05-10 06:03:27 +08:00 via Android
    @LonnyWong 看到这个正好问一句,有什么好用的 webshell 吗
    LonnyWong
        41
    LonnyWong  
       2022-05-10 06:44:10 +08:00 via iPhone
    @diaosi 你可以参考 https://github.com/trzsz/trzsz.js/tree/main/examples/addon 这个代码自己建一个,要自己加一下登录鉴权的功能。
    qbmiller
        42
    qbmiller  
       2022-05-10 09:43:00 +08:00 via Android
    膜拜
    littlewing
        43
    littlewing  
       2022-05-10 21:26:34 +08:00
    看到 C 写的先赞一个
    Zoyo94
        44
    Zoyo94  
       2022-05-12 16:22:46 +08:00
    我目前用的是 autossh 跳板机 ssh -N -f -D 端口转发 。
    LonnyWong
        45
    LonnyWong  
       2022-05-13 09:11:56 +08:00 via iPhone
    @Chipmunker 你在 windows 用的是什么终端?是在 cmd 或 powershell 中运行 ssh 登录到远程的吗?

    我想,需要在某处运行楼主的软件,将 ssh 进程包起来,才能使用的。
    LonnyWong
        46
    LonnyWong  
       2022-05-13 09:13:54 +08:00 via iPhone
    @beordle 在 windows 中运行时,你的 pty 是怎么实现的?好像没找到 windows 相关的代码。
    beordle
        47
    beordle  
    OP
       2022-05-13 12:10:18 +08:00
    @buubiu 我的应用在 Windows 上是直接在 cygwin 或者是 WSL 编译运行的。
    beordle
        48
    beordle  
    OP
       2022-05-13 12:10:56 +08:00
    @LonnyWong @buubiu @ 错人..抱歉
    LonnyWong
        49
    LonnyWong  
       2022-05-13 16:33:00 +08:00 via iPhone
    @beordle 运行的时候是要在 cygwin 中,还是可以在 cmd 中(只要安装了 cygwin )?
    beordle
        50
    beordle  
    OP
       2022-05-13 17:43:04 +08:00 via iPhone
    @LonnyWong 普通 cmd 可以的~
    nicevar
        51
    nicevar  
       2022-05-13 21:03:26 +08:00
    很强,好东西,用来开发调试很方便
    maskerTUI
        52
    maskerTUI  
       2022-05-27 20:20:12 +08:00
    改天试试
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2867 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 13:10 · PVG 21:10 · LAX 06:10 · JFK 09:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.