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:1080
(socks5
在本地做 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_config
的 GatewayPorts
为 yes
(修改完需要重启 sshd)