如何搭建一个基于WebSocket的反向隧道
背景
如何利用VPS构建一个反向隧道?
- 有了一台VPS,但是因为在大陆访问速度慢的原因,所以需要使用CloudFlare加速
- 我需要在外网访问家里的一些服务,所以需要一个反向tunnel,即能够从外网访问内网服务
- 问题是,frp等工具都不太好用,一是直接使用容易被流量识别;二是不支持通过CloudFlare加速
- 还有就是,原本的域名上也有一个博客,所以需要特定path才走tunnel
在上面的限制下,试了好几个工具,最终发现wstunnel能够满足上面的要求。
最终方案画成图就是:
按照图中的方案,我们一步一步搭建。
服务端/VPS
从图中可以看出,在VPS上,我们需要一个nginx,用来:
- 正常访问流量走web服务,特定前缀的websocket流量转发给wstunnel-server
- wstunnel-server从nginx接收数据,由于是本地访问,所以只需要使用ws协议接收
- wstunnel-server需要有一定的认证能力
在原有的nginx配置中,中添加如下location,让所有/wstunnel
的流量转发到wstunnel-server:
1 | location /wstunnel { |
然后我们启动wstunnel-server:
1 | wstunnel server ws://127.0.0.1:8080 \ |
其中的--restrict-http-upgrade-path-prefix wstunnel-password
表示连接时需要在/wstunnel-password
路径下发起连接。
这样配置后,如果其他人不知道这个路径就无法连接,起到一个认证的作用。
客户端
在客户端
- 使用wss协议向服务端发送数据
- wss发起连接的时候,需要在特定前缀下
那么,使用如下命令,代表在socks5://[::1]:1212
启动了一个sock5代理服务,在http://[::1]:8012
启动了一个HTTP代理服务:
1 | wstunnel client wss://xxx.net --http-upgrade-path-prefix wstunnel-password \ |
然后我们就可以使用浏览器加SwitchyOmega扩展,来测试下上面的代理服务。
当然,在上面的配置中,我们只能通过这个tunnel访问其他服务,是一个正向的隧道。
不要忘记,我们最终的需求是如何让公网能够访问我们在内网的服务。
比如,我们想要通过VPS的8002端口,来访问本地8001端口上的一个服务,那么命令如下:
1 | wstunnel client wss://xxx.net --http-upgrade-path-prefix wstunnel-password \ |
这时候,我们怎么验证下这个反向隧道是正常的呢?
启动一个测试服务,验证下
我们在本地的8002端口,启动一个测试Web服务:
1 | python3 -m http.server 8002 |
然后,通过curl访问vpsIP:8001
,就能看到测试服务已经可以访问了:
1 | curl http://ipip:8002/ -i |
如何搭建一个基于WebSocket的反向隧道