深度主题-wifidirect
2023年4月3日发(作者:netgear 默认密码)
PHP正确获取客户端IP地址
现状
⽬前主流的函数⽅法:
<?php
functiongetIp()
{
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);
}
echogetIp();
测试
curl伪造IP请求:
$ch=curl_init('http://localhost/');
//通⽤设置
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
REMOTE_ADDR:是直接从TCP中获取的IP,基本不会被伪造!
返回查看$_SERVER数组,发现【REMOTE_ADDR】显⽰正确的IP!
所以直接⽤$_SERVER['REMOTE_ADDR']就解决问题了?
其实还不⾏,如果客户端和服务器之间存在代理服务器,【REMOTE_ADDR】的值是最后⼀个代理服务器的IP!
只有第⼀台接收客户端请求的代理服务器的【REMOTE_ADDR】值才是客户的真实IP地址,要把该值传递下去!
解决⽅案
1.客户端和服务器直连
<?php
functionget_client_ip()
{
$ip=$_SERVER['REMOTE_ADDR'];
return$ip;
}
2.客户端和服务器存在中间代理
第⼀层nginx代理设置:
proxy_set_headerX-Forwarded-For$remote_addr;
其他层nginx代理设置:
proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;
PHP代码:
<?php
functionget_client_ip()
{
$ip=null;
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$ip=explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
$ip=trim(current($ip));
}
return$ip;
}
更多推荐
获取ip地址
发布评论