用ssh反向代理让不联网服务器上网

最近需要在一个不能连接外网的集群上配置一些东西,十分麻烦。跟一个博士师兄交流后了解到可以用ssh的反向代理的方式让集群连接到外网。

这个情景是这样的,就是我们可以从本地用ssh连接到服务器,但是服务器无法上网。

我参考了SSH 命令的三种代理功能(-L/-R/-D),大概了解了具体的做法。我在Host A上操作,可以访问Host B上在Port B端口的进程,也可以用ssh连接到Host C。因此我可以用如下的命令:

1
HostA$ ssh -R HostC:PortC:HostB:PortB user@HostC

在这里也就是说,Host A可以访问HostB:PortB,而为了让HostC也可以访问到,就用ssh -R建立一个端口监听,让Host C把这个端口的所有数据转发给Host A,Host A再转发给HostB:PortB。同内网下的 HostA/HostB 也可以是同一台机器,换句话说就是内网 HostA 把自己可以访问的端口暴露给了外网 HostC。

另外值得注意的是,需要在HostC上的/etc/ssh/sshd_config开启:

1
GatewayPorts yes

并重启ssh服务。

因为我的Windows电脑上刚好有clash做代理,所以就直接用这个代理的端口号127.0.0.1:7890来做代理。

因此我执行:

1
ssh -R xx.xx.xx.xx:7890:127.0.0.1:7890 user@xx.xx.xx.xx

xx.xx.xx.xx是我的目标服务器的IP地址。在远程服务器上的端口可以自己根据需要调整。

连接进去后就可以配置环境变量,告诉目标机器代理端口为7890即可。然后就可以在远程的服务器用我Windows本的Clash代理上Google:

1
export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890

image-20220202221601293

这个办法也确实可以用于解决远程服务器无法访问外网的情况,不过如果没有root权限且GatewayPorts没有被打开的话也没有办法。