基于wstunnel的反向隧道配置

需求

因为家里一条宽带换成移动的,没有外网IP了,所以从外面接入不太方便,IPv6虽然也是个方案,但是内网那台arm小机器是很老的Debian7,没有驱动也升级不了系统,还是搞个隧道简单点。

之前《使用docker和wstun实现隧道和反向隧道》,但是这个用Node.js实现的太笨重了,而且debian7上也装不了docker。还好现在有新方案,就是这个用Rust实现的wstunnel。一个可执行文件轻松跑起,还支持32位arm linux。

简单起见这里不再说正向隧道的配置了,参考前文,换成wstunnel即可。下面只说反向隧道的。

服务端

直接运行是最简单的:

wstunnel server ws://[::]:8080

但是这样有个安全风险就是只要能连接到这个websocket服务端就可以任意映射端口,等于绕过了防火墙的检查。

虽然官方建议是可以加上https和随机的path-prefix加以防护,但我觉得还是直接包进docker里更保险一点。

用Rust的好处之一就是这是独立可执行文件,没有依赖,直接用一个最小系统镜像(如alpine:3.22)就能运行:

docker run -d --name wstunnel -v $HOME/opt:/root/opt -p 127.0.0.1:8080:8080 -p 0.0.0.0:8022:8022 alpine:3.22 /root/opt/wstunnel server ws://[::]:8080

这个命令的功能就是用alpine:3.22的镜像来运行wstunnel(放在$HOME/opt下),把websocket端口8080映射到本地,把反向隧道的端口8022映射到外网。这样即使有其它的客户端想到映射别的端口,或者映射服务器的端口都无法实现,因为都是在docker容器里面。

当然为了保险起见,可以继续叠加官方的安全手段。

客户端

因为无法运行docker,就只能直接运行了:

wstunnel client -R 'tcp://[::]:8022:127.0.0.1:22' ws://server:8080

为了保持运行,我实际上是用supervisor加持了一下。

远程的地址实际上也不是这个,而是用https代理过的。

服务端https代理配置

也是使用Nginx的反向代理,如前文:

# 在http段加上全局配置
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}
# 在server段加上代理配置
    location / {
        proxy_pass http://127.0.0.1:8080;
        
        # 启用WebSocket支持的关键配置
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        # 保持连接和代理头信息
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # 设置较长的超时时间以保持持久连接
        proxy_read_timeout 86400;
        proxy_send_timeout 86400;
        keepalive_timeout 86400;
    }

这样配置以后,只要服务端和客户端保持运行,就可以通过服务端的8022端口连接到客户机的22。

推送到[go4pro.org]