• 源于师姐提到的一个问题:什么是反向代理?
  • 之前本科在自己建站以及做学校项目的时候其实有涉及到,但没进行总结
  • 趁此机会埋个坑,把代理的东西好好理一理,顺便讲讲 VPN 啥的
  • 未完待续~

基本概念

什么是代理?

  • 代理:顾名思义,根据汉语拆词为字进行组词就很好理解。代,代表;理,处理。所以代理往往是描述了一个中间人所要做的工作,就是代表某一方进行某些事情的处理。
  • 对于商业场景中关于代理的故事就不再此处进行赘述,此处则主要探讨在计算机领域中主要涉及到的 网络代理

网络代理

  • 一种特殊的网络服务,英文名做 Proxy,允许一个网络终端(一般为客户端)通过这个服务与另一个网络终端(一般为服务器)进行非直接的连接。一些网关、路由器等网络设备具备网络代理功能。一般认为代理服务有利于保障网络终端的隐私或安全,防止攻击。
  • 一个完整的代理请求过程为:客户端首先与代理服务器创建连接,接着根据代理服务器所使用的代理协议,请求对目标服务器创建连接、或者获得目标服务器的指定资源(如:文件)。在后一种情况中,代理服务器可能对目标服务器的资源下载至本地缓存,如果客户端所要获取的资源在代理服务器的缓存之中,则代理服务器并不会向目标服务器发送请求,而是直接传回已缓存的资源。
  • 一些代理协议允许代理服务器改变客户端的原始请求、目标服务器的原始响应,以满足代理协议的需要。代理服务器的选项和设置在计算机程序中,通常包括一个“防火墙”,允许用户输入代理地址,它会遮盖他们的网络活动,可以允许绕过互联网过滤实现网络访问。

常见类型

正向代理(Forward Proxy)

基本原理

  • 常见的场景中所提到的代理一般都是指 正向代理。
  • 正向代理是指 用户 利用 代理服务器 访问 目标服务器。
  • 主要目的:隐藏客户端,忽略客户端的差异。
image

使用场景

  • 访问本地无法访问的服务器;最简单的例子就是翻墙,还有针对部分只能内网访问的场景,往往需要借助代理服务器,才能进行相关资源的访问(譬如实验室的服务器)。
  • 缓存(Cahce)作用:cache技术与代理服务技术是紧密联系的,假设我们的电脑是用户A,我们想通过代理服务器X访问服务器A上的数据B,如果在这之前,有人通过代理服务器X访问过该数据,那么代理服务器X会把数据B保存一段时间,在这段时间内,如果我们想访问数据B,代理服务器会直接把缓存的数据B直接发给我们,而不会再去访问服务器A。
  • 权限控制:防火墙授权代理服务器访问权限,客户端通过正向代理可以通过防火墙;故部分内网的服务器会限制登录IP为代理服务器IP,从而保证只有在已知代理服务器的情况下才能访问内网服务器。
  • 隐藏访问者:通过配置,目标服务器无法获取真实客户端信息,只能获取到代理服务器的信息,针对部分安全性要求较高的业务,往往需要隐藏客户端。(BTW,但严格意义上仍是不安全的)
  • 针对某些限制 IP 访问次数的场景,常常使用 IP 代理池来进行代理访问,从而使用代理服务器的多个 IP 来进行相关访问。特别是某些数据爬取的场景。

实现方式

  • 利用 Nginx、Apache 等 Web 服务器来引入相关代理模块并进行配置,从而转发客户端传递来的 Web 请求。
  • 利用一些软件,进行相应协议的通信加密和转换,实现对应的功能。

延申

  • 正向代理根据协议划分主要有HTTP、HTTP over TLS(HTTPS)、Socks、Socks over TLS几种。其中,HTTP和Socks无法用于翻墙,HTTPS和Socks over TLS可以用于翻墙。
  • 四种代理协议都可以通过“用户先将数据发给代理服务器,再由代理服务器转发给目的服务器”的方法达到翻墙目的。但由于HTTP和Socks都是明文协议,GFW可以通过检查数据包内的内容得知用户的真实意图,进而拦截数据包。所以,HTTP和Socks一般只用作本地代理。而HTTPS协议是加密通讯,GFW无法得知数据包内的真实内容,类似于关键词过滤的手段无法施展。HTTPS代理的流量特征和我们平时访问网站时所产生的HTTPS流量几乎一模一样,GFW无法分辨,稳定性爆表。

常见正向代理软件

tinyproxy
gost
  • GO 语言实现的安全隧道
  • Github Repo
  • 官方教程
  • 经过简单对比,gost 代理性能要比 tinyproxy 好很多。
  • 运行教程:
wget http://github.com/ginuerzh/gost/releases/download/v2.11.1/gost-linux-amd64-2.11.1.gz
gunzip gost-linux-amd64-2.11.1.gz
mv gost-linux-amd64-2.11.1 gost
chmod +x gost
nohup ./gost -L :9002 > ./gost.log &

反向代理

基本原理

  • 正向代理代理的是用户,而反向代理则相反,代理对象是目标服务器。
  • 反向代理:指 服务端 利用 代理服务器 给 用户 提供服务。
  • 主要目的:向客户端隐藏服务端的细节,由代理服务器统一接管,并根据适当的策略(负载均衡等)来分发相应的请求并最终通过代理服务器进行返回。
image

使用场景

  • 保护和隐藏原始资源服务器;用户A始终认为它访问的是原始服务器B而不是代理服务器Z,但实用际上反向代理服务器接受用户A的应答,从原始资源服务器B中取得用户A的需求资源,然后发送给用户A。由于防火墙的作用,只允许代理服务器Z访问原始资源服务器B。尽管在这个虚拟的环境下,防火墙和反向代理的共同作用保护了原始资源服务器B,但用户A并不知情。
image
  • 负载均衡:当反向代理服务器不止一个的时候,我们甚至可以把它们做成集群,当更多的用户访问资源服务器B的时候,让不同的代理服务器Z(x)去应答不同的用户,然后发送不同用户需要的资源。当然反向代理服务器像正向代理服务器一样拥有CACHE的作用,它可以缓存原始资源服务器B的资源,而不是每次都要向原始资源服务器B请求数据,特别是一些静态的数据,比如图片和文件,如果这些反向代理服务器能够做到和用户X来自同一个网络,那么用户X访问反向代理服务器X,就会得到很高质量的速度。这正是CDN技术的核心。
image
  • 缓存作用:数据缓存在代理服务器上,如果客户端请求的内容在缓存中则不去访问目标主机;

延申

  • 利用反向代理实现内网穿透。通过使用SSH将内网服务器的22端口对应地转发到反向代理服务器上的某个端口,从而建立了从内网服务器到代理服务器的反向代理;接着在代理服务器上通过将本机的某个端口转发到反向代理服务端口来建立正向代理,从而使得在外网的任何一台服务器都可】通过代理服务器上提供的正向代理来对远程的内网服务器进行操作。
  • 常见的内网穿透工具可参考文献中的【7】。
ssh
  • ssh 参数解释:
    • -f 后台执行ssh指令
    • -C 允许压缩数据
    • -N 不执行远程指令
    • -R 将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口
    • -L 将本地机(客户机)的某个端口转发到远端指定机器的指定端口
    • -p 指定远程主机的端口
  • ssh 正向代理配置:ssh -fCNL
  • ssh 反向代理配置:ssh -fCNR
场景
  • 内网服务器 I:192.168.3.126 | ssh 端口:22
  • 外网服务器 O:45.45.45.45 | ssh 端口:33
  • step1 在内网服务器 I 上建立 内网服务器 I 到 外网服务器 O 的反向代理
# 该命令将本地的ssh端口反向代理到了远程服务器的7777端口
# 参数解释:ssh -fCNR 
#   外网服务器对应的代理通信 IP:Port - 7777  (IP可省略)
#   内网服务器对应的代理通信 IP:Port - localhost:22 (为了建立ssh连接使用了22端口)
#   登陆远程服务器使用的信息 [email protected] -p port - [email protected] -p 33
#
[[email protected] ~]# ssh -fCNR 7777:localhost:22 [email protected] -p 33

  • step2 在外网服务器 O 上建立 正向代理
# 该命令建立了本机端口 7776 到 7777 的正向代理
# 参数解释:ssh -fCNR 
#   服务器A 对应的代理通信 IP:Port - *:7776  (IP可省略,将会使用命令末尾的IP)
#   服务器B 对应的代理通信 IP:Port - localhost:7777 (对应内网服务器反向代理的端口)
#   登陆A 服务器使用的信息 IP -p port - localhost -p 33
#
[[email protected] ~]# ssh -fCNL *:7776:localhost:7777 localhost -p 33
  • step3 使用ssh连接内网服务器
# 该命令建立了到外网服务器指定端口的ssh连接
# 1. 7776 端口对应地被正向代理转发到了 7777端口;
# 2. 7777 端口对应地被反向代理代理到了 内网服务器的22端口
# 3. 从而建立起了对内网服务器的 ssh 连接
#
> ssh -p 7776 [email protected]
  • (可选) step4 内网服务器配置ssh免密登陆并使用 autossh来进行自动重连
# 免密登录
ssh-copy-id [email protected]

# 安装autossh
yum install autossh

# 同 ssh 的参数一致
# 多了一个 -M port的参数,主要用于外网服务器接受内网服务器的信息
autossh -M 7775 -fCNR 7777:localhost:22 [email protected] -p 33 
  • (可选) step5 将autossh加入内网服务器开机启动项,并使配置生效
vi /etc/rc.d/rc.local

# 添加内容
autossh -M 7775 -fCNR 7777:localhost:22 [email protected] -p 33

# 赋予权限
chmod +x /etc/rc.d/rc.local

Last but not least (猴子都能看懂的步骤)

【Firstly】
先告诉憨憨们
xx.xx.xx.xx => 你的跳板机IP
8111 => 跳板机对应的端口

【SSH 公钥私钥生成】
ssh-keygen

【ssh 免密登录:(免密失败检查公私钥和跳板机配置)】
ssh-copy-id [email protected]
ssh -vvv xx.xx.xx.xx // 查看日志错误信息

【centos 安装 autossh】
yum install autossh
【安装失败使用 RPM 安装】
wget http://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/a/autossh-1.4g-1.el7.x86_64.rpm
rpm -i autossh-1.4g-1.el7.x86_64.rpm
【检查是否安装成功】
rpm -qa | grep autossh

【autossh 反代命令】:
autossh -M 2222 -NfR 8111:localhost:22 [email protected] -p 22

// -M 后的端口时 autossh 接收错误消息自动重连的,不用管
// -NfR 后的端口才是你最后会用的,你懂我意思吧~
// -p 22 列出来是怕有的憨憨默认ssh端口不是22的,专门写出来!!
//很清楚了吧~

【连接时 connection refused,需要打开跳板机端口,重启ssh service】
vim /etc/ssh/sshd_config
...
GatewayPorts yes
AuthorizedKeysFile .ssh/authorized_keys
...

sudo /etc/init.d/ssh restart

【反代连接】
ssh [email protected] -p 8111

参考文献