Skip to content

Instantly share code, notes, and snippets.

@wwek
Created December 29, 2016 07:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wwek/cb59f5b3bd835be6b370f9b3efaa9163 to your computer and use it in GitHub Desktop.
Save wwek/cb59f5b3bd835be6b370f9b3efaa9163 to your computer and use it in GitHub Desktop.
客户端真实IP获取探针,用于在CDN,LB等多层代理环境下客户端真实IP获取检查
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>信息</title>
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css">
<!-- 可选的Bootstrap主题文件(一般不用引入) -->
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap-theme.min.css">
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="http://cdn.bootcss.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
</head>
<body>
<div class="bs-example">
<table class="table">
<!-- <caption>信息</caption> -->
<thead>
<tr>
<th>项</th>
<th>值</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<tr>
<td>客户端ip</td>
<td><?php echo get_client_ip(0,true)?></td>
<td>过CDN(LB等)get_client_ip函数获取的客户端真实ip</td>
</tr>
<tr>
<td>HTTP_X_FORWARDED_FOR</td>
<td><?php echo $_SERVER['HTTP_X_FORWARDED_FOR']?></td>
<td>HTTP_X_FORWARDED_FOR, 如果有CDN(LB)","分割的第一个IP就是真实客户端ip,CDN(LB)会把客户端真实IP写入本值</td>
</tr>
<tr>
<td>HTTP_CLIENT_IP</td>
<td><?php echo $_SERVER['HTTP_CLIENT_IP']?></td>
<td>HTTP_CLIENT_IP, 如果有CDN(LB)","分割的第一个IP就是真实客户端ip,不是标准,后端程序取ip的时候先取HTTP_X_FORWARDED_FOR</td>
</tr>
<tr>
<tr>
<td>HTTP_CF_CONNECTING_IP</td>
<td><?php echo $_SERVER['HTTP_CF_CONNECTING_IP']?></td>
<td></td>
</tr>
<tr>
<td>HTTP_X_REAL_IP</td>
<td><?php echo $_SERVER['HTTP_X_REAL_IP']?></td>
<td></td>
</tr>
<tr>
<td>REMOTE_ADDR</td>
<td><?php echo $_SERVER['REMOTE_ADDR'];?></td>
<td>直接访问源服务器就是客户端IP,直接访问有匿名代理就是匿名代理服务器的IP,过CDN后就是CDN节点IP</td>
</tr>
<tr>
<td>SERVER_ADDR</td>
<td><?php echo $_SERVER['SERVER_ADDR']?></td>
<td>服务器IP</td>
</tr>
<tr>
<td>HTTP_HOST</td>
<td><?php echo $_SERVER['HTTP_HOST']?></td>
<td>HTTP_HOST HTTP主机头</td>
</tr>
<tr>
<td>SERVER_NAME</td>
<td><?php echo $_SERVER['SERVER_NAME']?></td>
<td>SERVER_NAME</td>
</tr>
<tr>
<td>HTTP_USER_AGENT</td>
<td><?php echo $_SERVER['HTTP_USER_AGENT']?></td>
<td>浏览器UA</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
<?php
#print_r($_SERVER);
/**
* 获取客户端IP地址
* @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
* @param boolean $adv 是否进行高级模式获取(有可能被伪装)
* @return mixed
*/
function get_client_ip($type = 0,$adv=false) {
$type = $type ? 1 : 0;
static $ip = NULL;
if ($ip !== NULL) return $ip[$type];
if($adv){
//特别注意,使用本项,必须保证客户端不是直接访问源服务器,前面一定的有CDN接入层
//实际上在CDN确定的情况下,写死
//如果客户端是直接访问源服务器,除REMOTE_ADDR外都可能被伪造
if (isset($_SERVER['HTTP_X_REAL_IP'])) {
//大多数CDN,本项取
$ip = $_SERVER['HTTP_X_REAL_IP'];
}elseif (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
//百度云加速、Cloudflare,本项取
$ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
}elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
//某些CDN会把客户端真实IP写入本项,","号分割的第一个
$arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$pos = array_search('unknown',$arr);
if(false !== $pos) unset($arr[$pos]);
$ip = trim($arr[0]);
}elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
}elseif (isset($_SERVER['REMOTE_ADDR'])) {
//客户端直接访问源服务器,客户端真实IP取本项
$ip = $_SERVER['REMOTE_ADDR'];
}
}elseif (isset($_SERVER['REMOTE_ADDR'])) {
$ip = $_SERVER['REMOTE_ADDR'];
}
// IP地址合法验证
$long = sprintf("%u",ip2long($ip));
$ip = $long ? array($ip, $long) : array('0.0.0.0', 0);
return $ip[$type];
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment