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

2022-06-01 17:27:32 +08:00
 wlh233

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

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

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

2067 次点击
所在节点    分享创造
6 条回复
zagfai
2022-06-02 00:29:20 +08:00
好像很厉害的样子
saltbo
2022-06-02 14:17:31 +08:00
> 但用户 C 可能是个完全不懂技术的人,我要花时间教给 C 怎么去配置。

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

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

frp 的 STCP 我觉得完全没必要。因为这种工具干的事都是在应用协议里面传输 TCP ,所以完全可以在应用层加上鉴权,对接 oidc 即可。
wlh233
2022-06-02 15:52:22 +08:00
@saltbo 感谢反馈。对于反向代理的这部分,除了鉴权以外,我还希望是做到隐蔽性,也就是公网服务器 B 上不会开放新的端口,要实现这个不在 C 处安装客户端我认为是做不到的。我感觉这也是 frp 的 STCP 模式存在的意义。现在的设计是在这个前提下进行的。
molezznet
2022-06-03 01:58:31 +08:00
nps 的客户端傻瓜 , 可以直接发送后傻瓜运行。 所有配置都由服务端设置
wlh233
2022-06-09 23:53:49 +08:00
@molezz765 之前没听说过,去看了一下功能还挺多的。相比之下我这个比较简陋,就只有基本功能。无配置的思路是一致的,他的无配置我看是由服务端返回客户端需要的命令行参数,我是直接放在了客户端文件里,给分发带来了一些困难,好处是对于占大多数的 windows 用户来说,只需要双击运行。
molezznet
2022-06-10 09:07:54 +08:00
@wlh233 嗯 就是看需求和实际使用的变化情况了。 有家基于这个的商业服务,其实也是为了拉低门槛, 让客户运行后自行在 web 新建端口

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/856773

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX