目前获取IP的方式都是通过:1.HTTP_X_FORWARDED_FOR 2.HTTP_CLIENT_IP 3.REMOTE_ADDR
然而这1和2种方式都可以通过伪造header头信息进行伪造
但是第三种想要伪造会困难很多,1和2的信息获取都是通过http header信息获取,所以伪造的难易度低很多,但是REMOTE_ADDR获取的方式是在TCP协议握手的时候所得到的数据,要想伪造这里的REMOTE_ADDR的信息的话,这就涉及到TCP层。困难层度大增,尤其是在PHP对于底层数据操作。
HTTP_X_FORWARDED_FOR
获取到的是代理服务器的IP,经过几个代理的时候,会出现一连串的IP通过逗号链
在不出现伪造的乐观情况下,规格为(X-Forwarded-For: client1, proxy1, proxy2),
第一个是原始的客户端IP地址,后边的IP是依次访问的代理服务器的IP,最后一个即最后一次访问到的代理服务器IP
HTTP_CLIENT_IP
获取到的是代理服务器的IP
REMOTE_ADDR
获取到的是服务器和客户端第一次TCP握手链接时的IP
在PHP里面很多程序在获取IP的时候,不管是用$_SERVER还是getenv,采取获取IP的流程很多时候都是这样:
HTTP_X_FORWARDED_FOR ==>HTTP_CLIENT_IP ==> REMOTE_ADDR
但是因为出现伪造这种情况,所以HTTP_X_FORWARDED_FOR 和 HTTP_CLIENT_IP这种都是很危险的,可以轻易通过伪造进行欺骗,假如没有对IP进行验证的话,甚至能造成SQL注入。所以在获取IP的时候好的习惯是对IP进行格式进行验证
顺便说下$_SERVER和getenv的区别,getenv不支持IIS的isapi方式运行的php
参考链接:
http://www.dewen.io/q/1391/curl+%E5%A6%82%E4%BD%95%E6%A8%A1%E6%8B%9Fremote_addr+%E5%8F%96%E7%9A%84ip
http://segmentfault.com/q/1010000000095850