想象一下我们传统的三层架构,如果我们想统一把批量修改数据的SQL屏蔽掉,那么直接修改DAO层,统一拦截处理就可以了。类似的,网络系统也是如此,在传统的客户端和服务端之间,可能会存在各种各样的代理服务器,用于实现各种功能。
常见的代理有两种:普通代理-中间人代理,隧道代理。
4.6.1、普通代理话不多说,我们直接上图,说明一下代理的工作原理:
代理既是服务器,又是客户端。代理工作原理:客户端向代理发送请求,代理接收请求并与客户端建立连接,然后转发请求给服务器,服务器接收请求并与代理建立连接,最终把响应按原路返回。
当然,实际的场景中,客户端与服务器可能包含多个代理服务器。
代理最常见到的请求头RFC 7230中定义了Via,用于追踪请求和响应消息转发情况;RFC 7239中定义了X-Forwarded-For用于记录客户端请求的来源IP;X-Real-IP可以用于记录客户端实际请求IP,该请求头不属于任何标准。
Via:**Via** 是一个通用首部,是由代理服务器添加的,适用于正向和反向代理,在请求和响应首部中均可出现。这个消息首部可以用来追踪消息转发情况,防止循环请求,以及识别在请求或响应传递链中消息发送者对于协议的支持能力;
X-Forwarded-For:每经过一级代理(匿名代理除外),代理服务器都会把这次请求的来源IP追加在X-Forwarded-For中:
X-Forwarded-For: client, proxy1, proxy2
注意:与服务器直连的代理的IP不会被追加到X-Forwarded-For中,该代理可以通过TCP连接的Remote Address字段获取到与服务器直连的代理IP地址;
X-Real-IP:记录与当前代理服务器建立TCP连接的客户端的IP,一般通过$remote_addr获取,这个IP是上一级代理的IP,如果没有代理,则是客户端的IP;
一般我们在Nginx中会做如下配置:
location / { proxy_set_header X-Real-IP $remote_addr; // 与服务器建立TCP连接的客户端的IP作为X-Real-IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; // 追加请求的来源IP ... }假设我们所有的代理都按照如上设置,那么请求头变化情况则如下:
客户端IP伪造注意,X-Forwarded-For是可以伪造的,一些通过X-Forwarded-For获取到的客户端IP来限制刷投票的系统就可以通过伪造该请求头来打到刷票的效果,如果客户端请求显示指定了X-Forwarded-For
X-Forwarded-For: 192.168.1.2
那么,服务器接收到的该请求头,第一个IP就是这个伪造的IP了。
如何防范IP伪造?
方法一:在对外Nginx服务器上配置:
proxy_set_header X-Forwarded-For $remote_addr;这样,第一个IP就是从TCP连接的客户端IP地址了,不会读取客户端伪造的X-Forwarded-For。
方法二:从右到左遍历X-Forwarded-For的IP,剔除已知代理服务器IP和内网IP,获取到第一个符合条件的IP。
正向代理和反向代理工作在客户端的代理我们称为正向代理。使用正向代理的时候,需要在客户端配置使用的代理服务器,正向代理对服务端透明。我们常用的Fiddler、charles抓包工具,以及访问一些外网网站的代理工具就属于正向代理。
如下图:
正向代理通常用于:
缓存;
屏蔽某些不健康的网站;
通过代理访问原本无法访问的网站;
上网认证,对用于进行访问授权...
工作在服务端的代理我们称为反向代理。使用反向代理的时候,无需在客户端进行设置,反向代理对客户端透明。反向代理(Reverse Proxy)这个名词有点让人摸不着头脑,不过就这么叫吧,我们常用的nginx就是属于反向代理。
如下图:
通用把80作为http的端口,把433端口作为https的端口。
反向代理通常用于:
负载均衡;
服务端缓存;
流量隔离;
日志;
金丝雀发布...
代理中的持久连接 Connection请求头我们得先介绍下Connection请求头字段。