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

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

  •  7
     
  •   beordle ·
    beordle · 104 天前 · 12813 次点击
    这是一个创建于 104 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    https://github.com/beordle/termtunnel

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

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

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

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

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

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

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

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

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

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

    @quzard 也支持简单的端口转发,sock5 很多时候是满足不了需求吗?
    quzard
        29
    quzard  
       98 天前 via Android   ❤️ 1
    @beordle 有些不支持 socks5 比如 wget
    LonnyWong
        30
    LonnyWong  
       98 天前
    @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  
       98 天前 via iPhone
    @beordle 刚回复完,然后看到 lwIP ,原来可以通过流控和重传来解决 tmux 丢包的问题。太强了!
    beordle
        32
    beordle  
    OP
       98 天前
    @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  
       98 天前 via iPhone
    思路有意思 implementation 还没看 但是提供的 API 很 intuitive 👍
    LonnyWong
        34
    LonnyWong  
       98 天前 via iPhone
    @beordle 太强了,建议你为 tmux 提个 PR 。加个启动参数,或.tmux.conf 配置项,默认不启用,对于有需要的自行启用就好。
    beordle
        35
    beordle  
    OP
       97 天前
    @quzard 1.5.1 增加了 http 协议支持,和 socks5 同端口。
    quzard
        36
    quzard  
       97 天前 via Android
    @beordle 高效率👍
    lamCJ
        37
    lamCJ  
       96 天前 via Android
    如果内网网络做了 IP/域名白名单,能 bypass 吗
    beordle
        38
    beordle  
    OP
       96 天前 via iPhone
    不能,只能以某个主机(对端)的身份去发起请求。不可能超出这个范畴。当然你也可以让他们一群机器都通过你的主机连到互联网…配合..frp..?
    buubiu
        39
    buubiu  
       96 天前
    star 了
    diaosi
        40
    diaosi  
       96 天前 via Android
    @LonnyWong 看到这个正好问一句,有什么好用的 webshell 吗
    LonnyWong
        41
    LonnyWong  
       96 天前 via iPhone
    @diaosi 你可以参考 https://github.com/trzsz/trzsz.js/tree/main/examples/addon 这个代码自己建一个,要自己加一下登录鉴权的功能。
    qbmiller
        42
    qbmiller  
       95 天前 via Android
    膜拜
    littlewing
        43
    littlewing  
       95 天前
    看到 C 写的先赞一个
    Zoyo94
        44
    Zoyo94  
       93 天前
    我目前用的是 autossh 跳板机 ssh -N -f -D 端口转发 。
    LonnyWong
        45
    LonnyWong  
       92 天前 via iPhone
    @Chipmunker 你在 windows 用的是什么终端?是在 cmd 或 powershell 中运行 ssh 登录到远程的吗?

    我想,需要在某处运行楼主的软件,将 ssh 进程包起来,才能使用的。
    LonnyWong
        46
    LonnyWong  
       92 天前 via iPhone
    @beordle 在 windows 中运行时,你的 pty 是怎么实现的?好像没找到 windows 相关的代码。
    beordle
        47
    beordle  
    OP
       92 天前
    @buubiu 我的应用在 Windows 上是直接在 cygwin 或者是 WSL 编译运行的。
    beordle
        48
    beordle  
    OP
       92 天前
    @LonnyWong @buubiu @ 错人..抱歉
    LonnyWong
        49
    LonnyWong  
       92 天前 via iPhone
    @beordle 运行的时候是要在 cygwin 中,还是可以在 cmd 中(只要安装了 cygwin )?
    beordle
        50
    beordle  
    OP
       92 天前 via iPhone
    @LonnyWong 普通 cmd 可以的~
    nicevar
        51
    nicevar  
       92 天前
    很强,好东西,用来开发调试很方便
    maskerTUI
        52
    maskerTUI  
       78 天前
    改天试试
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1268 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 23:52 · PVG 07:52 · LAX 16:52 · JFK 19:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.