通过CloudFlare获取正确的访客IP
Get correct visitor IP through CloudFlare
我正在使用转售给我的其他人的 cPanel。
这可能意味着我不能使用 mod_cloudflare
我想获取访问者的IP,而不是CloudFlare IP。
我正在使用的代码部分:
$_SERVER['REMOTE_ADDR']
该行将获取cloud flare的IP,而不是原始用户的IP。
有什么办法可以得到访问者的原始IP地址吗?
可以,但是 without access to the server configuration,您将无法使用 $_SERVER['REMOTE_ADDR']
。
但是,您可以still use X-Forwarded-For
and CF-Connecting-IP
。两者都可以在 $_SERVER
超级全局中使用。
我在我的应用程序中使用了以下函数:http://ipaddress.standingtech.com/ to exclude CloudFlare IP address
<?php
/*
* @param $ips = array of IP address
*/
function clear_flare_ips($ips){
foreach($ips as $index => $ip){
if(is_in_flareips($ip)){
unset($ips[$index]);
}
}
ksort($ips);
return $ips;
}
function is_in_flareips($ip){
$flareips = getflareips();
foreach($flareips as $range){
if(ip_in_range( $ip, $range )){
return true;
}
}
return false;
}
function getallips(){
if (isset($_SERVER['HTTP_CLIENT_IP']))
$ipaddress[] = $_SERVER['HTTP_CLIENT_IP'];
if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
$ipaddress[] = $_SERVER['HTTP_X_FORWARDED_FOR'];
if(isset($_SERVER['HTTP_X_FORWARDED']))
$ipaddress[] = $_SERVER['HTTP_X_FORWARDED'];
if(isset($_SERVER['HTTP_FORWARDED_FOR']))
$ipaddress[] = $_SERVER['HTTP_FORWARDED_FOR'];
if(isset($_SERVER['HTTP_FORWARDED']))
$ipaddress[] = $_SERVER['HTTP_FORWARDED'];
if(isset($_SERVER['REMOTE_ADDR']))
$ipaddress[] = $_SERVER['REMOTE_ADDR'];
if(count($ipaddress) == 0)
$ipaddress[] = 'UNKNOWN';
return $ipaddress;
}
function getflareips(){
/*
https://www.cloudflare.com/ips-v4
*/
return array(
'103.21.244.0/22',
'103.22.200.0/22',
'103.31.4.0/22',
'104.16.0.0/12',
'108.162.192.0/18',
'131.0.72.0/22',
'141.101.64.0/18',
'162.158.0.0/15',
'172.64.0.0/13',
'173.245.48.0/20',
'188.114.96.0/20',
'190.93.240.0/20',
'197.234.240.0/22',
'198.41.128.0/17',
'199.27.128.0/21'
);
}
function ip_in_range( $ip, $range ) {
/**
* Check if a given ip is in a network
* @param string $ip IP to check in IPV4 format eg. 127.0.0.1
* @param string $range IP/CIDR netmask eg. 127.0.0.0/24, also 127.0.0.1 is accepted and /32 assumed
* @return boolean true if the ip is in this range / false if not.
*/
if ( strpos( $range, '/' ) == false ) {
$range .= '/32';
}
// $range is in IP/CIDR format eg 127.0.0.1/24
list( $range, $netmask ) = explode( '/', $range, 2 );
$range_decimal = ip2long( $range );
$ip_decimal = ip2long( $ip );
$wildcard_decimal = pow( 2, ( 32 - $netmask ) ) - 1;
$netmask_decimal = ~ $wildcard_decimal;
return ( ( $ip_decimal & $netmask_decimal ) == ( $range_decimal & $netmask_decimal ) );
}
Akam 的回答过于复杂,无法解决。
这是一个更简单的方法:
if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
}
我正在使用转售给我的其他人的 cPanel。
这可能意味着我不能使用 mod_cloudflare
我想获取访问者的IP,而不是CloudFlare IP。 我正在使用的代码部分:
$_SERVER['REMOTE_ADDR']
该行将获取cloud flare的IP,而不是原始用户的IP。
有什么办法可以得到访问者的原始IP地址吗?
可以,但是 without access to the server configuration,您将无法使用 $_SERVER['REMOTE_ADDR']
。
但是,您可以still use X-Forwarded-For
and CF-Connecting-IP
。两者都可以在 $_SERVER
超级全局中使用。
我在我的应用程序中使用了以下函数:http://ipaddress.standingtech.com/ to exclude CloudFlare IP address
<?php
/*
* @param $ips = array of IP address
*/
function clear_flare_ips($ips){
foreach($ips as $index => $ip){
if(is_in_flareips($ip)){
unset($ips[$index]);
}
}
ksort($ips);
return $ips;
}
function is_in_flareips($ip){
$flareips = getflareips();
foreach($flareips as $range){
if(ip_in_range( $ip, $range )){
return true;
}
}
return false;
}
function getallips(){
if (isset($_SERVER['HTTP_CLIENT_IP']))
$ipaddress[] = $_SERVER['HTTP_CLIENT_IP'];
if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
$ipaddress[] = $_SERVER['HTTP_X_FORWARDED_FOR'];
if(isset($_SERVER['HTTP_X_FORWARDED']))
$ipaddress[] = $_SERVER['HTTP_X_FORWARDED'];
if(isset($_SERVER['HTTP_FORWARDED_FOR']))
$ipaddress[] = $_SERVER['HTTP_FORWARDED_FOR'];
if(isset($_SERVER['HTTP_FORWARDED']))
$ipaddress[] = $_SERVER['HTTP_FORWARDED'];
if(isset($_SERVER['REMOTE_ADDR']))
$ipaddress[] = $_SERVER['REMOTE_ADDR'];
if(count($ipaddress) == 0)
$ipaddress[] = 'UNKNOWN';
return $ipaddress;
}
function getflareips(){
/*
https://www.cloudflare.com/ips-v4
*/
return array(
'103.21.244.0/22',
'103.22.200.0/22',
'103.31.4.0/22',
'104.16.0.0/12',
'108.162.192.0/18',
'131.0.72.0/22',
'141.101.64.0/18',
'162.158.0.0/15',
'172.64.0.0/13',
'173.245.48.0/20',
'188.114.96.0/20',
'190.93.240.0/20',
'197.234.240.0/22',
'198.41.128.0/17',
'199.27.128.0/21'
);
}
function ip_in_range( $ip, $range ) {
/**
* Check if a given ip is in a network
* @param string $ip IP to check in IPV4 format eg. 127.0.0.1
* @param string $range IP/CIDR netmask eg. 127.0.0.0/24, also 127.0.0.1 is accepted and /32 assumed
* @return boolean true if the ip is in this range / false if not.
*/
if ( strpos( $range, '/' ) == false ) {
$range .= '/32';
}
// $range is in IP/CIDR format eg 127.0.0.1/24
list( $range, $netmask ) = explode( '/', $range, 2 );
$range_decimal = ip2long( $range );
$ip_decimal = ip2long( $ip );
$wildcard_decimal = pow( 2, ( 32 - $netmask ) ) - 1;
$netmask_decimal = ~ $wildcard_decimal;
return ( ( $ip_decimal & $netmask_decimal ) == ( $range_decimal & $netmask_decimal ) );
}
Akam 的回答过于复杂,无法解决。 这是一个更简单的方法:
if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
}