SSH 正反向代理

由于经常要连到服务器上,经常会遇到这些问题:

  • 只有服务器可以访问一些线上资源,本地无法访问,测试麻烦
  • 服务器可以高速访问一些网站,本地很慢,需要给本地加速
  • 本地可以高速访问一些网站,服务器很慢,需要给服务器加速

简单可以总结成两种场景:

  • 服务器想用本地的网络
  • 本地想用服务器的网络

以我实际遇到的场景为例:共有 3 台服务器,Server、Proxy、Forbidden。Server 为国内云厂商服务器,Proxy 为海外服务器,Forbidden 为海外用于部署 Tor 节点的服务器(国内已无法直连)

(感觉好浪费钱,3 台大部分时间都空闲着……)

SSH 正向代理

正向代理指通过某个隧道访问远端资源,如使用公司 VPN 连入内网访问内部资源(或者访问不存在的网站)。

对于这种行为,有两种不同的形式:

  • 只代理网络里的某个端口,如映射 localhost:port1 -> proxy:port2
  • 代理所有请求,如本机所有发向对应端口的连接都由服务端执行实际的请求

端口代理

如同场景里提到的,Forbidden 服务器国内是无法直连的,如果需要经常性连上去操作数据非常不便,因此希望可以使用 Proxy 服务器中转下 SSH 连接。

期望实现如下图的效果:Proxy 服务器在 22 端口承接自己的 SSH 服务,将 2048 端口转发至 Forbidden 服务器的 22 端口实现 SSH 转发。

正向代理端口正向代理端口

在这里,实际上要做的只是端口转发,使用 ssh -L 0.0.0.0:2048:forbidden:22 user@forbidden 即可建立一个 SSH 端口转发。


严格来说,更好的办法是使用其他服务,而非 SSH 转发(由于网络波动,SSH 连接可能会断开,这可能会导致转发失效)

更推荐使用 Nginx 的 TCP 转发功能(如果使用 HTTP 反向代理,也可以实现网站加速)。

nginx.conf 最外层 添加如下代码(也可以使用 include 引入),实现 Proxy 服务器 2222 端口到 Forbidden 22 端口的转发。

stream {
    upstream tcpssh {
        hash $remote_addr consistent;
        server forbidden.example.com:22 max_fails=3 fail_timeout=10s;
    }
    server{
        listen 2222;
        proxy_connect_timeout 20s;
        proxy_timeout 5m;
        proxy_pass tcpssh;
    }
}

全流量代理

如果你有一个 CN2 GIA 服务器,那么再去忍受如同百度云一样的网速去下载开发依赖是没有必要的。但是我们往往可能不需要配置复杂的代理工具,可以简单使用 SSH 代理实现(据说 SSH 代理本身混淆性不如专业性的抗审查工具,长时间使用可能会被筛选出来)。

使用 ssh -D 127.0.0.1:1080 user@proxy,即可以在建立连接的同时,实现本地开放 socks5://127.0.0.1:1080 作为代理端口

接下来就是常规操作了,使用 export HTTP_PROXY=socks5://127.0.0.1:1080; export HTTPS_PROXY=$HTTP_PROXY 设定代理即可。对于 curl 也可以使用 curl https://www.google.com --proxy socks5h://127.0.0.1:1080socks5 在本地做 DNS 解析,可能会被 DNS 污染;socks5h 会在服务端做 DNS 解析,稳定性更高)。

SSH 反向代理

反向代理,更多出现在前后端分离部署的场景,由于跨域问题的存在,前后端往往需要部署到同一个服务下。通常在 Nginx 中,会使用 proxy_pass 来将服务代理到某个路径下。这种与正向代理操作相反的被称作反向代理。

如果我们本地有自带负载均衡的加速代理,那么在服务端再去部署一个代理是没必要的(在内网环境下,往往是不允许随意连接外网,安装奇怪的软件的)。这时,可以让服务器使用本地的代理工具联网,加速依赖下载。

如下图,我们可能会希望借助 Proxy 服务器加速 Server 下载依赖,那么在本地已经有了 1080 端口的 socks5 加速代理后,只需要在连接到 Server 时,使用 ssh -R 127.0.0.1:10808:127.0.0.1:1080 user@server 即可以建立一个 Server 10808 端口到本地 1080 端口的映射。接下来就是正常的设置代理的操作(可见全流量代理部分)

反向代理反向代理

后台运行

除去反向代理,我们通常需要交互式执行命令外,正向代理的两种形式我们往往不需要交互式 Shell,只希望有一个背景程序执行转发任务。在这里有一些可选的参数来提升体验:

  • -C: 压缩数据传输(使用 gzip 压缩)
  • -q: 不输出信息
  • -T: 不需要分配终端
  • -n: 不监听输入流
  • -N: 不执行命令
  • -f: 后台执行

对于这些短命令,可以放在一起,写成 -CNTnfq(从那天能翻墙)

监听外网

如果需要 SSH 监控 0.0.0.0 的需求,需要修改 /etc/ssh/sshd_configGatewayPortsyes(修改完需要重启 sshd)

参考资料