网络之X-Forwarded-For

Posted luojiabao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络之X-Forwarded-For相关的知识,希望对你有一定的参考价值。

参考 https://www.cnblogs.com/huaxingtianxia/p/6369089.html

一个请求可能经过的路径:客户端=>(正向代理=>透明代理=>服务器反向代理=>)Web服务器

 

其中正向代理、透明代理、服务器反向代理这三个环节并不一定存在。

  • 什么是正向代理呢,很多企业会在自己的出口网关上设置代理(主要是为了加速和节省流量)。
  • 透明代理可能是用户自己设置的代理(比如为了FQ,这样也绕开了公司的正向代理)。
  • 服务器反向代理是部署在 Web 服务器前面的,主要原因是为了负载均衡和安全考虑。

从上面大家也看出来了,因为有了各种代理,才会导致 REMOTE_ADDR 这个全局变量产生了一定的歧义,为了让 Web 服务器获取到真实的客户端 IP,X-Forwarded-For 出现了,这个协议头也是由 Squid 起草的(Squid 应该是最早的代理软件之一)。

这个协议头的格式:X-Forwarded-For: client, proxy1, proxy2; 

client 表示用户的真实 IP,每经过一次代理服务器,代理服务器会在这个头增加用户的 IP(有点拗口)。

注意最后一个代理服务器请求 Web 服务器的时候是不会将自己的 IP 附加到 X-Forwarded-For 头上的,最后一个代理服务器的 IP 地址应该通过$_SERVER[‘REMOTE_ADDR‘]获取。

举个例子:
用户的 IP 为(A),分别经过两个代理服务器(B,C),最后到达 Web 服务器,那么Web 服务器接收到的 X-Forwarded-For 就是 A,B。

那么 php 如何获取真实客户端 IP 呢?

$ip = isset($_SERVER[‘HTTP_X_FORWARDED_FOR‘]) ? trim($_SERVER[‘HTTP_X_FORWARDED_FOR‘]) : ‘‘;
if (!$ip) 
    $ip = isset($_SERVER[‘REMOTE_ADDR‘]) ? trim($_SERVER[‘REMOTE_ADDR‘]) : ‘‘;

$a = explode(‘|‘, str_replace(‘,‘, ‘|‘, $ip));
$ip = trim($a[0]);

这里预先说明下,假设这两个代理服务器都是好的代理服务器,没有伪造 HTTP_X_FORWARDED_FOR。

  • X-Forwarded-For 表示 nginx 接收到的头,原样的转发过来(假如不转发,Web 服务器就不能获取这个头)。
  • X-Real-IP,这是一个内部协议头(就是反向代理服务器和 Web 服务器约定的),这个头表示连接反向代理服务器的 IP 地址(这个地址不能伪造),

对于 Web 服务器来说,安全有两个纬度,第一个纬度是 REMOTE_ADDR 这个头,这个头不能伪造。第二个纬度就是 X-Forwarded-For,但是这个头是可以伪造的。

以上是关于网络之X-Forwarded-For的主要内容,如果未能解决你的问题,请参考以下文章

网络骇客入门之网络编程:网络应知应会

k8s网络之Flannel网络

大型园区网络排错篇之概念开山之作

云原生之DockerDocker的网络管理

k8s网络之设计与实现

计算机网络基础