PHP 获取客户端ip地址

1、若是没有使用代理服务器,php

REMOTE_ADDR= 客户端IP HTTP_X_FORWARDED_FOR= 没数值或不显示html

$ip = $_SERVER['REMOTE_ADDR'];

2、使用透明代理,nginx

REMOTE_ADDR= 最后一个代理服务器 IP
HTTP_X_FORWARDED_FOR= 客户端真实 IP (通过多个代理服务器时,这个值相似:221.5.252.160, 203.98.182.163, 203.129.72.215)json

这类代理还会将客户真实ip发送到请求对象,没法隐藏真实ip。数组

$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];

3、使用普通匿名代理服务器,浏览器

REMOTE_ADDR= 最后一个代理服务器 IP
HTTP_X_FORWARDED_FOR = 代理服务器 IP (通过多个代理服务器时,这个值相似:203.98.182.163, 203.98.182.163, 203.129.72.215)安全

这样就隐藏了客户端的真实ip,但服务器会知道客户端是经过代理服务器去访问的。bash

4、使用欺骗性代理服务器,服务器

REMOTE_ADDR= 代理服务器 IP
HTTP_X_FORWARDED_FOR= 随机的 IP(通过多个代理服务器时,这个值相似:220.4.251.159, 203.98.182.163, 203.129.72.215)curl

服务器能够识别到时经过代理服务器访问的,但发送给目标服务器的是虚假ip。

5、使用高匿名代理,

REMOTE_ADDR= 代理服务器 IP HTTP_X_FORWARDED_FOR= 没数值或不显示

使用这种代理时,不一样浏览器不一样设备会返回不一样的ip头信息,所以PHP使用$_SERVER["REMOTE_ADDR"]$_SERVER["HTTP_X_FORWARDED_FOR"] 获取的值多是空值也多是“unknown”值。

PHP获取ip代码方法1:

function getip() { static $realip; if (isset($_SERVER)) { if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $realip = $_SERVER['HTTP_X_FORWARDED_FOR']; } else if (isset($_SERVER['HTTP_CLIENT_IP'])) { $realip = $_SERVER['HTTP_CLIENT_IP']; } else { $realip = $_SERVER['REMOTE_ADDR']; } } else { if (getenv('HTTP_X_FORWARDED_FOR')) { $realip = getenv('HTTP_X_FORWARDED_FOR'); } else if (getenv('HTTP_CLIENT_IP')) { $realip = getenv('HTTP_CLIENT_IP'); } else { $realip = getenv('REMOTE_ADDR'); } } return $realip; } 

PHP获取ip代码方法2:

function getip(){ $ip=false; if(!empty($_SERVER['HTTP_CLIENT_IP'])){ $ip=$_SERVER['HTTP_CLIENT_IP']; } if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){ $ips=explode (', ', $_SERVER['HTTP_X_FORWARDED_FOR']); if($ip){ array_unshift($ips, $ip); $ip=FALSE; } for ($i=0; $i < count($ips); $i++){ if(!eregi ('^(10│172.16│192.168).', $ips[$i])){ $ip=$ips[$i]; break; } } } return ($ip ? $ip : $_SERVER['REMOTE_ADDR']); } 

根据ip获取归属地信息

/** 获取 IP 地理位置 * 淘宝IP接口 * @Return: array */ function getCity($ip = '') { $url="http://ip.taobao.com/service/getIpInfo.php?ip=".$ip; $ip=json_decode(file_get_contents($url)); if((string)$ip->code=='1'){ return false; } $data = (array)$ip->data; return $data; }



现状

目前主流的函数方法:

<?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请求:

$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

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; }

 另:

 

<?php
function getIP()
{
static $realip;
if (isset($_SERVER)){
if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])){
$realip = $_SERVER["HTTP_X_FORWARDED_FOR"];
} else if (isset($_SERVER["HTTP_CLIENT_IP"])) {
$realip = $_SERVER["HTTP_CLIENT_IP"];
} else {
$realip = $_SERVER["REMOTE_ADDR"];
}
} else {
if (getenv("HTTP_X_FORWARDED_FOR")){
$realip = getenv("HTTP_X_FORWARDED_FOR");
} else if (getenv("HTTP_CLIENT_IP")) {
$realip = getenv("HTTP_CLIENT_IP");
} else {
$realip = getenv("REMOTE_ADDR");
}
}
return $realip;
}

echo getIP();
?>

简易

<?php
$ip = $_SERVER['REMOTE_ADDR'];

echo $ip;?>

相关文章
相关标签/搜索