代理可以理解为是一个服务器,它一般作为客户端和服务端的中介。没有代理的情况下客户端的请求直达服务端,而有代理时客户端和服务端的信息通过代理进行交互。就像大城市租房中介一样,租客和房东通过中介来交换信息。
生活中常说的代理(如)一般指正向代理,正向代理的目的一般是隐藏客户端。使用正向代理时客户端的请求全部由服务器代发。我们都知道一般情况下我们的电脑无法访问谷歌,但是如果有一个代理服务器可以访问google而我们也能访问到代理服务器,那么我们就可以使用它来作媒介访问谷歌。此时谷歌只能看到代理服务器,我们的真实ip被隐藏了起来。
流程简单来看如下:
一个代理服务器可以为多个服务端服务。
和正向代理相反,反向代理的目的是隐藏服务端。一般当我们访问某度或者某宝的官网时,上面的url不是真实的服务端ip地址。它会将请求发给真实的服务器,然后真实的服务器也通过它与客户端进行交互。
反向代理流程如下:
客户端把消息发到代理服务器,代理服务器将消息传给真实服务器。
正向代理和反向代理可以结合使用,当我们使用正向代理访问谷歌时,谷歌也在进行反向代理。此时流程如下:
这样就做到了同时隐藏客户端和服务端的真实地址。
我们在实际使用网络时可能经过多层代理,而有一些http头可以记录中间ip或者真实源ip。
remote_addr代表直接连接服务器的ip,如果客户端的消息没有经过任何代理传到服务器,那么服务器就会把remote_addr设为客户端的IP,如果使用了代理那么服务器的remote_addr会设为与服务器直连的代理ip。
remote_addr几乎不可被伪造,因为它是直接从tcp连接的信息获取的,如果伪造那么这个tcp将无法建立(如果从中间的路由器来伪造ip还是有可能建立tcp的,不过这不属于应用层范畴)。
x-real-ip是一个自定义http头,一般会被设置为emote_addr。它是一个自定义http头。它通常用来记录真实ip。因此x-real-ip也是记录直接连接的ip,因此当经过多级代理时只会记录倒数第二给代理服务器ip,如proxy1-3对应ip为ip1-3,那么最终传到真实服务器会记录ip2,因为ip已经是最后一个代理服务器,没有代理服务器会填它的ip,因此多层代理时 x-real-ip只会记录倒数第二给x-real-ip。但是如果只在proxy1开启x-real-ip,那么最终的http消息只会记录proxy1前也就是客户端的ip。
一般x-real-ip也不可被伪造。
x-forwarded-for简称XFF,是http协议的一个扩展头部,一般情况下这个头部需要手动开启。
XFF的格式一般如下:
X-Forwarded-For: client_IP, proxy1_IP, proxy2_IP
当代理服务器proxy1收到来自client的消息时会往该词条添加client的ip,proxy2收到来自proxy1的消息时会往该词条添加proxy1的ip,同理proxy3会添加proxy2的ip,如果此时proxy3是最后一个代理,直接发往真实的服务器,那么该词条将不会包含proxy3的ip。也就是说在一般情况下XFF不会记录与真实服务器直连的ip,只会记录所有间接相连的ip。
假如ip为ip0的客户端需要经过proxy1-3三个代理服务器,且它们的ip为ip1-3,那么它们的开启关系对应的XFF内容如下:
#1.proxy1-3均开启XFF
X-Forwarded-For: ip0,ip1,ip2
#2.仅proxy1开启XFF
X-Forwarded-For: ip0
#3.仅proxy2开启XFF
X-Forwarded-For: ip1
#4.仅proxy3开启XFF
X-Forwarded-For: ip2
#5.仅proxy1-2开启XFF
X-Forwarded-For: ip0,ip1
#6.仅proxy1,proxy3开启XFF:
X-Forwarded-For: ip0,ip2
#7.仅proxy2-3开启XFF:
X-Forwarded-For: ip1,ip2
可以看出XFF开启后代理服务器仅在该词条添加向自己发消息的ip。
正常情况下有了XFF可以轻松找到每个中间地址,进而找到端地址,但是该消息可以被伪造。
假定客户端ip为ip0,服务端需要进行两层反向代理,对应的地址为ip1,ip2。那么正常情况应该如下:
X-Forwarded-For: ip0,ip1
但是假定客户端伪造了一个请求头,如下:
X-Forwarded-For: 假ip1,假ip2
那么经过代理后就是这样的:
X-Forwarded-For: 假ip1,假ip2,ip0,ip1
这样服务器就会拿到错误ip。此时由于反向代理服务器和真实服务器是一家,因此可以通过确定反向代理服务器的数量来从后向前找到ip0。也可以在proxy1处理时用remote_addr来覆盖收到的XFF头。
xff注入也是sql注入的一种。XFF注入原理是修改XFF头,使其带有SQL语句,然后对服务器的系统进行sql注入,使服务器执行自定义的SQL命令,从而可以查询网站数据库的信息或篡改删除网站数据库。
xff防范与sql注入的防范类似,主要都是通过过滤敏感sql字符来实现的。