主要想要解决的需求是有时想把一个端口暴露在公网,但又不想完全公开,只想开放给认证过的客户端,通过转发到客户端的本地端口来访问。
frp 的 STCP 模式能解决这个问题,实现方式是端口提供者 A 、公网服务器 B 、访问者 C 三个机器都进行配置。这样做忽略了一点,就是 A 和 B 可能都是我自己,但用户 C 可能是个完全不懂技术的人,我要花时间教给 C 怎么去配置。
VPN 也可以解决这个需求,也还是会有上述配置问题。一些新型 VPN 如 tailscale 主打零配置,但前提是公网服务器由他来提供。
于是就自己写了一个简单的工具,实现了类似 ssh 隧道的端口转发功能,加密和认证用的是 noise 协议,握手采用跟 wireguard 一样提前交换密钥的形式。特色就是客户端无需配置,服务端的配置也只需要执行命令,不用复制粘贴密钥。
关于零配置我的实现非常暴力:在二进制程序的数据段预留一部分空间,当需要新的客户端时,服务端程序复制一份空白的客户端,修改二进制文件把生成的配置存进去,得到一个认证过的客户端。把这个认证过的客户端发给对方,使用时直接无参数运行。
远端 1 <-> 客户端 <-> 服务端 <-> 远端 2
ssh -L
模式:通过服务端访问远端 2 的静态端口。ssh -D
模式:通过服务端内置的 socks5 服务访问动态的远端 2 。ssh -R
模式:将远端 1(固定端口或内建 socks5)暴露给服务端并注册一个 service id 。ssh -R visitor
模式:只有在此模式下具有相同 service id 的客户端才能访问暴露的端口。Noise_IK_25519_ChaChaPoly_BLAKE2s
协议握手.-L
模式: 把某些软件绑定在 127.0.0.1 的 socks5 服务加密共享给局域网中的某几台机器,从而无需绑定 0.0.0.0 完全在局域网公开-D
模式:内网其中一台机器有公网端口时,作为 VPN 服务的简单替代,从外部访问内网任意一台机器-R
模式:把内网机器的端口暴露至公网服务器,并且只允许同样认证过的客户端访问想法非常简单,作者也比较菜,肯定会有潜在的安全缺陷,不推荐在生产环境使用,作者也不为可能出现的安全问题负责。
开发过程没有什么技术含量,基本都是用的现成的轮子。性能方面因为就我自己在用,目前没感觉出太大问题,没详细测过性能,有可能还不如 ssh 。
源码在:https://github.com/wlh320/portguard
感兴趣的网友欢迎一起探讨和改进。
1
zagfai 2022-06-02 00:29:20 +08:00
好像很厉害的样子
|
2
saltbo 2022-06-02 14:17:31 +08:00
> 但用户 C 可能是个完全不懂技术的人,我要花时间教给 C 怎么去配置。
你虽然解决了配置的问题,但是最终还是要 C 安装一个客户端。正常来说面向最终用户不应该压根不需要安装什么东西么? 针对需求:想把一个端口暴露在公网,但又不想完全公开,只想开放给认证过的客户端。 其实就是你暴露的服务自身没有鉴权能力,需要代理层帮助他完成鉴权嘛。我觉得正常来说 C 只需要:注册-> 登录 -> 使用。 frp 的 STCP 我觉得完全没必要。因为这种工具干的事都是在应用协议里面传输 TCP ,所以完全可以在应用层加上鉴权,对接 oidc 即可。 |
3
wlh233 OP @saltbo 感谢反馈。对于反向代理的这部分,除了鉴权以外,我还希望是做到隐蔽性,也就是公网服务器 B 上不会开放新的端口,要实现这个不在 C 处安装客户端我认为是做不到的。我感觉这也是 frp 的 STCP 模式存在的意义。现在的设计是在这个前提下进行的。
|
4
molezznet 2022-06-03 01:58:31 +08:00
nps 的客户端傻瓜 , 可以直接发送后傻瓜运行。 所有配置都由服务端设置
|