又一个命令行文件传输,这次用边缘函数做 TCP 打洞 - V2EX
爱意满满的作品展示区。
Contextualist

又一个命令行文件传输,这次用边缘函数做 TCP 打洞

  •  
  •   Contextualist
    Contextualist Jan 16, 2023 4158 views
    This topic created in 1235 days ago, the information mentioned may be changed or developed.

    简单来说,就是用 Deno deploy 这个跑 V8 的平台做建立点对点连接时打洞用的公共服务器。实现主要归功于 Deno deploy 的以下特性:

    • 作为 HTTP 服务器的 handler ,却可以拿到底层 TCP 连接的源 IP 和端口信息
    • BroadcastChannel API 让全球不同区域的实例可以实时通信

    具体可以参见我边缘函数的实现

    噱头归噱头,我也是真心想做一个比市面上已有的命令行文件传输更好用的工具。现有的工具设计时大部分是考虑传文件给他人的场景,但对于我来说,更多是在自己的不同服务器 /设备间传文件的场景。因此,大可不必每次传输都要求用户复制粘贴一段随机代号,身份验证信息可以提前存储到每台设备上。

    acp 使用体验上尽量贴近 cp ,发送端指定文件,接收端不需要指定任何信息。并且启动无分先后,两边都就绪后即开始协商建立连接传输。

    安装脚本详见 README(就下载个可执行文件然后初始化配置)

    最后忍不住说一句,边缘函数干这个实在是太适合了,轻量低成本低延迟,还颇有拆手机锂电池用来生火的风味

    项目在这: https://github.com/Contextualist/acp

    26 replies    2023-01-29 18:34:43 +08:00
    v2wtf
        1
    v2wtf  
       Jan 16, 2023
    问一下,多人同时使用的情况下,是如何判断谁发给谁的?是需要事先登录同一个账号?
    Contextualist
        2
    Contextualist  
    OP
       Jan 16, 2023
    @v2wtf 对于每个人的第一台设备,acp 在初始化配置 (acp --setup) 时会生成一个随机 ID ,随后的设备初始化配置会导入这个 ID (acp --setup-with '{"id":"... )。使用时会配对相同 ID 发起的、时间上最接近的两个请求。本来这个设计是给每个人自己给自己传文件用的,如果多个人间使用导入相同的配置也行,不过不太适合群发或者临时分享给陌生人。
    AS4694lAS4808
        3
    AS4694lAS4808  
       Jan 16, 2023
    如果是自己的服务器间传文件,用已经信任的密钥+scp+zerotier 应该也挺方便吧?
    我是写了个 shell 脚本,接受的参数是(服务器名,源文件 /文件夹地址,远程目录)。。
    haoxuexiaoyao
        4
    haoxuexiaoyao  
       Jan 16, 2023
    安全么 经过服务器么
    haoxuexiaoyao
        5
    haoxuexiaoyao  
       Jan 16, 2023
    可以局域网部署么
    duke807
        6
    duke807  
       Jan 16, 2023 via Android
    “边缘函数” 是什么意思?
    Contextualist
        7
    Contextualist  
    OP
       Jan 16, 2023
    @AS4694lAS4808 诚然,scp 的地位无可替代,跟它相比,acp 主要是为了省去打服务器名和远程目录的功夫。我自己的使用场景是:我登上一台机器,在其中某个目录深处工作到一半,需要把一些文件拷到当前目录下,作为接收只需要运行个不带参数的 acp ,然后发送端运行 acp path/to/files 即可。

    @haoxuexiaoyao 服务只用来做 TCP 打洞的信息交换,真正的文件通过点对点直连传输。所以服务端接收发送的数据只有两边的 ID 和 IP 地址端口。部署到 Deno Deploy 同时也是为了利用他们全球分布的节点,服务端就一个 Deno TypeScript 文件,理论上来说你在任意 vm 上拿 Deno 也能跑。
    Contextualist
        8
    Contextualist  
    OP
       Jan 16, 2023
    @duke807 边缘函数类似云函数,用户托管的代码只需要包含一个处理 HTTP 请求的函数。相比一般的云函数,边缘函数的运行时是 V8 (Chrome 和 Node.js 的 Javascript 引擎) 而不是完整的容器,因而部署成本低并且冷启动非常快。
    Actrace
        9
    Actrace  
       Jan 16, 2023
    这个项目太棒了!
    lysS
        10
    lysS  
       Jan 16, 2023
    我只知道 UDP 打洞的原理,TCP 打洞是不是要 root 权限发送 raw ip 包?
    duke807
        11
    duke807  
       Jan 16, 2023 via Android
    @Contextualist
    云函数又是什么?
    不用容器不就是经典的直接运行的 nodejs 之类的程序,不用 docker 而已么
    novolunt
        12
    novolunt  
       Jan 16, 2023
    没配置吗? receiver 怎么接收指定的 sender ,没看到配置
    建议使用 zstd 压缩,性能比 gzip 好
    novolunt
        13
    novolunt  
       Jan 16, 2023
    测试了下,可以穿透内外网,很棒。
    AS4694lAS4808
        14
    AS4694lAS4808  
       Jan 16, 2023 via Android
    @duke807 公有云提供的服务,你把代码传上去,不用管运行环境,公有云提供软硬件运行你的代码
    Contextualist
        15
    Contextualist  
    OP
       Jan 16, 2023
    @lysS 其实原理跟 UDP 打洞差不多,大概都是两边先各自跟第三方建立连接,再重用端口尝试互相连接。随着路由和设备支持的逐渐完善,现在 TCP 打洞成功率还是挺高的。不需要 root ,TCP socket 可以设置 SO_REUSEADDR 和 SO_REUSEPORT ,使同一个端口像 UDP 那样能同时被多个 socket 绑定。

    @duke807 云函数基本就是你把代码交给平台,运维完全交给他们,平台根据请求数量伸缩实例数量,按照实际运行消耗的 CPU 时间和内存计费,没请求时不收费。边缘函数平台的 V8 比普通 Node.js 增加了权限隔离和横向伸缩等等,基本上像一个不带操作系统的容器了。

    @novolunt 谢谢建议!我去看看
    gogf
        16
    gogf  
       Jan 16, 2023
    反馈个问题:

    Win10: acp --setup 之后,acp 发送文件,报错:failed to communicate with the bridge: io: read/write on closed pipe

    Linux 下正常

    而且 Windows 下貌似换个文件夹重新 setup ,id 、psk 就变了
    Contextualist
        17
    Contextualist  
    OP
       Jan 16, 2023
    @gogf 谢谢反馈!我找了台 Windows 的机子,没法复现,这两个现象我暂时没头绪,不过我可以尝试解释一下。
    > 报错:failed to communicate with the bridge: io: read/write on closed pipe
    能连上配对的公共服务,但是收发信息时连接断开了,不过我在服务端也没看见报错日志。
    > 貌似换个文件夹重新 setup ,id 、psk 就变了
    这就很奇怪,acp --setup 会去找 %APPDATA%\acp\config.json 配置在不在,找不到才会重新生成。你的 %APPDATA% 环境变量有发生改变吗?你能在那个位置找到配置吗? acp --setup 有其他报错吗?
    gogf
        18
    gogf  
       Jan 16, 2023
    @Contextualist
    环境变量没有发生变化,acp --setup 也没有报错信息,我后面测试正常了,配置文件存在

    不过我可以确定两次生成的参数确实不一样,应该是第一次因为某些原因没写进去

    收发文件的问题还存在
    Contextualist
        19
    Contextualist  
    OP
       Jan 16, 2023
    @gogf 我盯着代码又仔细想了一下,很有可能在连接配对公共服务时就出错了,但是这个错误没有被及时检查,被后来的收发信息错误覆盖了。所以可以快速尝试的事是看看你在终端里能不能正常访问 https://acp.deno.dev/get ,类似用 curl 发个 get 请求。如果这个也是正常的,你又不嫌麻烦,我明天修了这个报错顺序的问题,你再看看有没有新的错误信息。总之,感谢你的反馈!
    gogf
        20
    gogf  
       Jan 17, 2023
    @Contextualist
    确实无法访问,浏览器与 curl 都无法访问,挂了代理就行,移动宽带

    curl 报错:curl: (35) schannel: failed to receive handshake, SSL/TLS connection failed

    终端在可以正常 get “https://acp.deno.dev/get“的前提下,acp 还是无法正常使用,同样的报错内容
    Contextualist
        21
    Contextualist  
    OP
       Jan 17, 2023
    @gogf
    我大概明白了,你是在用 HTTPS_PROXY 之类的环境变量吗?这个目前的实现会无视代理的环境变量。我修了这个问题后自己试了一下,发现用代理时建立不了 P2P 连接,你如果想试一下可以试试目前最新提交的 CI artifacts: https://github.com/Contextualist/acp/actions/runs/3935796582 这个页面最底下可以下载。我得花时间想想这个问题是不是能解决的。

    如果一定需要代理,我自己试了一下目前那种基于 fake IP 的真全局代理(比如 ClashX Pro 的增强模式)是可以用的。
    gogf
        22
    gogf  
       Jan 17, 2023
    @Contextualist
    我原本是没有设置代理的,我的意思是设置了 HTTPS_PROXY 才能访问 “ https://acp.deno.dev/get

    另外,https://github.com/Contextualist/acp/actions/runs/3935796582 这里好像并不能下载最新版,不知道没有权限还是什么,没用过 GitHub Actions...
    Contextualist
        23
    Contextualist  
    OP
       Jan 17, 2023
    @gogf 嗯,我需要研究一下怎么样正确支持 HTTPS_PROXY ,等到时候有结果了跟你说。

    看了一下,GitHub Actions 好像需要登录才能下载 artifacts ,任意账户都行。如果不行,你也可以用我下载下来的这个: https://t.wss.ink/f/aa11yspjrlv
    Contextualist
        24
    Contextualist  
    OP
       Jan 18, 2023
    @gogf 实在是抱歉!我折腾了半天,还是没能解决跟代理一起使用的兼容问题,下面是初步结论(但感觉解释不太清楚

    对于使用代理的一方,只有代理服务器连接 acp.deno.dev 时使用的 IP 端口是对外可见的,但是这个 IP 端口实际上并不能被其他连接重用。
    如果另一方没使用代理并且有公网,那或许可以连接上,但是实际测试发现,使用代理的一方不能设置端口重用(似乎是 Go 的 bug )。

    对此,剩下的选择是你自己部署服务端(参见 https://github.com/Contextualist/acp/blob/main/docs/advanced.md#host-the-rendezvous-service-yourself ),在 Deno Deploy 上或者自己的服务器上都行,然后绑定一个自己的域名。
    sbilly
        25
    sbilly  
       Jan 29, 2023
    @Contextualist Linux/Windows/macOS 都支持吗?
    Contextualist
        26
    Contextualist  
    OP
       Jan 29, 2023
    @sbilly 都支持的,并且有相应的持续集成测试
    About     Help     Advertise     Blog     API     FAQ     Solana     5397 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 55ms UTC 07:10 PVG 15:10 LAX 00:10 JFK 03:10
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86