PHP取客户端的IP

有时候我们从$_SERVER中可以看到以下几种包含IP的字段:

  • $_SERVER["HTTP_CLIENT_IP"]
  • $_SERVER["HTTP_X_FORWARDED_FOR"]
  • $_SERVER["REMOTE_ADDR"]

$_SERVER["REMOTE_ADDR"]取客户端IP,有可能取得的是代理服务器的地址,而不是真正的客户端IP。而HTTP_CLIENT_IP和HTTP_X_FORWARDED_FOR 都可以被模拟,而且可能是代理服务器的。

因此,获取IP只需要一句话,$_SERVER["REMOTE_ADDR"] 这就足够了,没必要也不应该获取代理IP地址,REMOTE_ADDR是服务器和客户端握手后建立的tcp连接的数据帧里的,在应用层是无法修改的。当然,也不是绝对没有办法伪造的,IP协议可以完全自定义传输的数据,路由器这层也能伪造,但对于WEB程序员来说,是底层的东西,无法修改和伪造的。

  • $remote_addr

是nginx与客户端进行TCP连接过程中,获得的客户端真实地址. Remote Address 无法伪造,因为建立 TCP 连接需要三次握手,如果伪造了源 IP,无法建立 TCP 连接,更不会有后面的 HTTP 请求

  • X-Real-IP

是一个自定义头。X-Real-Ip 通常被 HTTP 代理用来表示与它产生 TCP 连接的设备 IP,这个设备可能是其他代理,也可能是真正的请求端。需要注意的是,X-Real-Ip 目前并不属于任何标准,代理和 Web 应用之间可以约定用任何自定义头来传递这个信息

  • X-Forwarded-For

X-Forwarded-For 是一个扩展头。HTTP/1.1(RFC 2616)协议并没有对它的定义,它最开始是由 Squid 这个缓存代理软件引入,用来表示 HTTP 请求端真实 IP,现在已经成为事实上的标准,被各大 HTTP 代理、负载均衡等转发服务广泛使用,并被写入 RFC 7239(Forwarded HTTP Extension)标准之中.