主要想要解决的需求是有时想把一个端口暴露在公网,但又不想完全公开,只想开放给认证过的客户端,通过转发到客户端的本地端口来访问。
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
感兴趣的网友欢迎一起探讨和改进。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.