一个客户端零配置的端口转发工具 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
wlh233
V2EX    分享创造

一个客户端零配置的端口转发工具

  •  
  •   wlh23
    wlh320 2022-06-01 17:27:32 +08:00 2488 次点击
    这是一个创建于 1234 天前的主题,其中的信息可能已经有所发展或是发生改变。

    主要想要解决的需求是有时想把一个端口暴露在公网,但又不想完全公开,只想开放给认证过的客户端,通过转发到客户端的本地端口来访问。

    frp 的 STCP 模式能解决这个问题,实现方式是端口提供者 A 、公网服务器 B 、访问者 C 三个机器都进行配置。这样做忽略了一点,就是 A 和 B 可能都是我自己,但用户 C 可能是个完全不懂技术的人,我要花时间教给 C 怎么去配置。

    VPN 也可以解决这个需求,也还是会有上述配置问题。一些新型 VPN 如 tailscale 主打零配置,但前提是公网服务器由他来提供。

    于是就自己写了一个简单的工具,实现了类似 ssh 隧道的端口转发功能,加密和认证用的是 noise 协议,握手采用跟 wireguard 一样提前交换密钥的形式。特色就是客户端无需配置,服务端的配置也只需要执行命令,不用复制粘贴密钥。

    关于零配置我的实现非常暴力:在二进制程序的数据段预留一部分空间,当需要新的客户端时,服务端程序复制一份空白的客户端,修改二进制文件把生成的配置存进去,得到一个认证过的客户端。把这个认证过的客户端发给对方,使用时直接无参数运行。

    工作原理

    远端 1 <-> 客户端 <-> 服务端 <-> 远端 2 
    1. 服务端绑定公网 IP 的一个端口.
    2. 远端可以是其他的公网端口(google.com:443), 本地端口(127.0.0.1:port), 或者动态端口(socks5).
    3. 客户端可以工作于以下任一模式:
      • ssh -L 模式:通过服务端访问远端 2 的静态端口。
      • ssh -D 模式:通过服务端内置的 socks5 服务访问动态的远端 2 。
      • ssh -R 模式:将远端 1(固定端口或内建 socks5)暴露给服务端并注册一个 service id
      • ssh -R visitor 模式:只有在此模式下具有相同 service id 的客户端才能访问暴露的端口。
    4. 客户端与服务端通过 Noise_IK_25519_ChaChaPoly_BLAKE2s 协议握手.
    5. 随后客户端与服务端之间的流量加密传输.

    使用场景举例

    1. -L 模式: 把某些软件绑定在 127.0.0.1 的 socks5 服务加密共享给局域网中的某几台机器,从而无需绑定 0.0.0.0 完全在局域网公开
    2. -D 模式:内网其中一台机器有公网端口时,作为 VPN 服务的简单替代,从外部访问内网任意一台机器
    3. -R 模式:把内网机器的端口暴露至公网服务器,并且只允许同样认证过的客户端访问

    想法非常简单,作者也比较菜,肯定会有潜在的安全缺陷,不推荐在生产环境使用,作者也为可能出现的安全问题负责。

    开发过程没有什么技术含量,基本都是用的现成的轮子。性能方面因为就我自己在用,目前没感觉出太大问题,没详细测过性能,有可能还不如 ssh 。

    源码在:https://github.com/wlh320/portguard

    感兴趣的网友欢迎一起探讨和改进。

    6 条回复    2022-06-10 09:07:54 +08:00
    zagfai
        1
    zagfai  
       2022-06-02 00:29:20 +08:00
    好像很厉害的样子
    saltbo
        2
    saltbo  
       2022-06-02 14:17:31 +08:00
    > 但用户 C 可能是个完全不懂技术的人,我要花时间教给 C 怎么去配置。

    你虽然解决了配置的问题,但是最终还是要 C 安装一个客户端。正常来说面向最终用户不应该压根不需要安装什么东西么?

    针对需求:想把一个端口暴露在公网,但又不想完全公开,只想开放给认证过的客户端。
    其实就是你暴露的服务自身没有鉴权能力,需要代理层帮助他完成鉴权嘛。我觉得正常来说 C 只需要:注册-> 登录 -> 使用。

    frp 的 STCP 我觉得完全没必要。因为这种工具干的事都是在应用协议里面传输 TCP ,所以完全可以在应用层加上鉴权,对接 oidc 即可。
    wlh233
        3
    wlh233  
    OP
       2022-06-02 15:52:22 +08:00
    @saltbo 感谢反馈。对于反向代理的这部分,除了鉴权以外,我还希望是做到隐蔽性,也就是公网服务器 B 上不会开放新的端口,要实现这个不在 C 处安装客户端我认为是做不到的。我感觉这也是 frp 的 STCP 模式存在的意义。现在的设计是在这个前提下进行的。
    molezznet
        4
    molezznet  
       2022-06-03 01:58:31 +08:00
    nps 的客户端傻瓜 , 可以直接发送后傻瓜运行。 所有配置都由服务端设置
    wlh233
        5
    wlh233  
    div class="badge op">OP
       2022-06-09 23:53:49 +08:00
    @molezz765 之前没听说过,去看了一下功能还挺多的。相比之下我这个比较简陋,就只有基本功能。无配置的思路是一致的,他的无配置我看是由服务端返回客户端需要的命令行参数,我是直接放在了客户端文件里,给分发带来了一些困难,好处是对于占大多数的 windows 用户来说,只需要双击运行。
    molezznet
        6
    molezznet  
       2022-06-10 09:07:54 +08:00
    @wlh233 嗯 就是看需求和实际使用的变化情况了。 有家基于这个的商业服务,其实也是为了拉低门槛, 让客户运行后自行在 web 新建端口
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2816 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 06:31 PVG 14:31 LAX 23:31 JFK 02:31
    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