PHP正确获取客户端IP地址
现状 目前主流的函数方法: <?php function getIp() { if ($_SERVER["HTTP_CLIENT_IP"] && strcasecmp($_SERVER["HTTP_CLIENT_IP"], "unknown")) { $ip = $_SERVER["HTTP_CLIENT_IP"]; } else { if ($_SERVER["HTTP_X_FORWARDED_FOR"] && strcasecmp($_SERVER["HTTP_X_FORWARDED_FOR"], "unknown")) { $ip = $_SERVER["HTTP_X_FORWARDED_FOR"]; } else { if ($_SERVER["REMOTE_ADDR"] && strcasecmp($_SERVER["REMOTE_ADDR"], "unknown")) { $ip = $_SERVER["REMOTE_ADDR"]; } else { if (isset ($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown") ) { $ip = $_SERVER['REMOTE_ADDR']; } else { $ip = "unknown"; } } } } return ($ip); } echo getIp(); 测试 curl伪造IP请求: <?php $ch = curl_init('http://localhost/ip.php'); //通用设置 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//不直接输出 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);//跟踪重定向 //伪造请求头 $ip = mt_rand(1, 255) . '.' . mt_rand(1, 255) . '.' . mt_rand(1, 255) . '.' . mt_rand(1, 255); $header = [ 'CLIENT-IP: ' . $ip, 'X-FORWARDED-FOR: ' . $ip, 'X-REAL-IP: ' . $ip, 'Accept-Language: zh-CN,zh;', ]; curl_setopt($ch, CURLOPT_HTTPHEADER, $header); $html = curl_exec($ch); curl_close($ch); echo $html; 输出SERVER数组,发现【HTTP_CLIENT_IP】、【HTTP_X_FORWARDED_FOR】、【HTTP_X_REAL_IP】是随机变动的IP地址。 主流方法根本不安全! 分析 为什么? HTTP_CLIENT_IP:存在于http请求的header HTTP_X_FORWARDED_FOR:请求转发路径,客户端IP,代理1IP,代理2IP...... HTTP_X_REAL_IP:这个用得比较少,暂不讨论。 这三个值都是从HTTP请求头获取的,所以并不可靠! REMOTE_ADDR:是直接从TCP中获取的IP,基本不会被伪造! 返回查看$_SERVER数组,发现【REMOTE_ADDR】显示正确的IP! 所以直接用 $_SERVER['REMOTE_ADDR'] 就解决问题了? 其实还不行,如果客户端和服务器之间存在代理服务器,【REMOTE_ADDR】的值是最后一个代理服务器的IP! 只有第一台接收客户端请求的代理服务器的【REMOTE_ADDR】值才是客户的真实IP地址,要把该值传递下去! 解决方案 1. 客户端和服务器直连 <?php function get_client_ip() { $ip = $_SERVER['REMOTE_ADDR']; return $ip; } 2. 客户端和服务器存在中间代理 第一层nginx代理设置: proxy_set_header X-Forwarded-For $remote_addr; 其他层nginx代理设置: proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; PHP代码: <?php function get_client_ip() { $ip = null; if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $ip = trim(current($ip)); } return $ip; } 参考 https://www.cnblogs.com/cmt/p/14580194.html
<< 上一篇
下一篇 >>
网友留言(0 条)