代理
一、认识
常见的代理有两种:普通代理(中间人代理),隧道代理
1.1 普通代理(中间人代理)
如图:代理服务器相当于一个中间人,一直帮两边传递东西,好可怜~~
不过它可以在中间可以帮我们过滤、缓存、负载均衡(多台服务器共用一台代理情况下)等一些处理
注意,实际场景中客户端和服务器之间可能有多个代理服务器
1.2 隧道代理
客户端通过CONNECT方法请求隧道代理创建一个可以到任意目标服务器和端口号的TCP连接,创建成功之后隧道代理只做请求和响应数据的转发,中间它不会做任何处理
为什么需要隧道代理呢?
我们都知道 https
服务是需要网站有证书的,而代理服务器显然没有,所以浏览器和代理之间无法创建 TLS
,所以就有了隧道代理,它把浏览器的数据原样透传,这样就实现了通过中间代理和服务端进行 TLS
握手,然后进行加密传输
1.3 正向代理
工作在客户端的代理为正向代理。使用正向代理的时候,需要在客户端配置需要使用的代理服务器,正向代理对服务端透明。比如抓包工具 Fiddler、Charles 以及访问一些外网网站的代理工具都是正向代理
正向代理通常用于
- 缓存
- 屏蔽某些不健康的网站
- 通过代理访问原本无法访问的网站
- 上网认证,对用户访问进行授权
1.4 反向代理
工作在服务端的代理称为反向代理。使用反向代理的时候,不需要在客户端进行设置,反向代理对客户端透明。如 Nginx 就是反向代理
反向代理通常用于:负载均衡、服务端缓存、流量隔离、日志、金丝雀发布
二、优势
-
突破访问限制:如访问一些单位或集团内部资源,或用国外代理服务器(翻墙)
-
安全性更高:上网者可以通过这种方式隐藏自己的 IP,免受攻击。还可以对数据过滤,对非法 IP 限流等
-
负载均衡:客户端请求先到代理服务器,而代理服务器后面有多少源服务器,IP 是多少,客户端是不知道的。因此,代理服务器收到请求后,通过特定的算法(随机算法、轮询、一致性 hash、LUR(最近最少使用) 算法这里不细说了)把请求分发给不同的源服务器,让各个源服务器负载尽量均衡
-
缓存代理:将内容缓存到代理服务器(这个下面一节详细说)
三、长连接
在各个代理和服务器、客户端节点之间是一段一段的 TCP 连接,客户端通过代理访问目标服务器也叫逐段传输,用于逐段传输的请求头叫逐段传输头。
逐段传输头会在每一段传输的中间代理中处理掉,不会传给下一个代理
标准的逐段传输头有:Keep-Alive、Transfer-Encoding、TE、Connection、Trailer、Upgrade、Proxy-Authorization、Proxy-Authenticate。
Connection头决定当前事务完成后是否关闭连接,如果该值为keep-alive,则连接是持久连接不会关闭,使得对同一服务器的请求可以继续在该连接上完成
四、请求头
-
Via
是一个能用首部,由代理服务器添加,适用于正向和反向代理,在请求和响应首部均可出现,这个消息首部可以用来追踪消息转发情况,防止循环请求,还可以识别在请求或响应传递链中消息发送者对于协议的支持能力。用法如下:
Via: 1.1 vegur
Via: HTTP/1.1 GWA
Via: 1.0 fred, 1.1 p.example.net -
X-Forwarded-For
记录客户端请求的来源IP,每经过一级代理(匿名代理除外),代理服务器都会把这次请求的来源IP追加进去
X-Forwarded-For: client,proxy1,proxy2
注意:与服务器直连的代理服务器的IP不会被追加进去,该代理可能过TCP连接的Remote Address字段获取到与服务器直连的代理服务器IP -
X-Real-IP
一般记录真实发出请求的客户端的IP,还有X-Forwarded-Host和X-Forwarded-Proto分别记录真实发出请求的客户端的域名和协议名
五、问题
5.1 代理中客户端 IP 伪造问题以及如何预防?
X-Forwarded-For是可以伪造的,比如一些通过X-Forwarded-For获取到客户端 IP 来限制刷票的系统就可以通过伪造该请求头达到刷票的目的,如果客户端请求显示指定了
X-Forwarded-For:192.168.1.108
那么服务端收到的这个请求头,第一个 IP 就是伪造的:
预防
- 在对外 Nginx 服务器上配置
location / {
proxy_set_header X-Forwarded-For $remote_addr
}
这样第一个 IP 就是从 TCP 连接客户端的 IP,不会读取伪造的
- 从右到左遍历 X-Forwarded-For 的 IP,排除已知代理服务器 IP 和内网 IP,获取到第一个符合条件的 IP 就可以了