IP 주소 검색에 사용할 수 있는 많은 $ _SERVER 변수 헤더 가 있다는 것을 알고 있습니다 . 위의 변수를 사용하여 사용자의 실제 IP 주소를 가장 정확하게 검색하는 방법에 대한 일반적인 합의가 있는지 궁금합니다.
나는 심도있는 솔루션을 찾으려고 노력하고 많은 소스를 기반으로 다음 코드를 생각해 냈습니다. 누군가가 대답에 구멍을 뚫어 내거나 아마도 더 정확한 것에 빛을 비출 수 있다면 그것을 좋아할 것입니다.
@Alix의 최적화가 포함 된 편집
/**
* Retrieves the best guess of the client's actual IP address.
* Takes into account numerous HTTP proxy headers due to variations
* in how different ISPs handle IP addresses in headers between hops.
*/
public function get_ip_address() {
// Check for shared internet/ISP IP
if (!empty($_SERVER['HTTP_CLIENT_IP']) && $this->validate_ip($_SERVER['HTTP_CLIENT_IP']))
return $_SERVER['HTTP_CLIENT_IP'];
// Check for IPs passing through proxies
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
// Check if multiple IP addresses exist in var
$iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
foreach ($iplist as $ip) {
if ($this->validate_ip($ip))
return $ip;
}
}
}
if (!empty($_SERVER['HTTP_X_FORWARDED']) && $this->validate_ip($_SERVER['HTTP_X_FORWARDED']))
return $_SERVER['HTTP_X_FORWARDED'];
if (!empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && $this->validate_ip($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']))
return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
if (!empty($_SERVER['HTTP_FORWARDED_FOR']) && $this->validate_ip($_SERVER['HTTP_FORWARDED_FOR']))
return $_SERVER['HTTP_FORWARDED_FOR'];
if (!empty($_SERVER['HTTP_FORWARDED']) && $this->validate_ip($_SERVER['HTTP_FORWARDED']))
return $_SERVER['HTTP_FORWARDED'];
// Return unreliable IP address since all else failed
return $_SERVER['REMOTE_ADDR'];
}
/**
* Ensures an IP address is both a valid IP address and does not fall within
* a private network range.
*
* @access public
* @param string $ip
*/
public function validate_ip($ip) {
if (filter_var($ip, FILTER_VALIDATE_IP,
FILTER_FLAG_IPV4 |
FILTER_FLAG_IPV6 |
FILTER_FLAG_NO_PRIV_RANGE |
FILTER_FLAG_NO_RES_RANGE) === false)
return false;
self::$ip = $ip;
return true;
}
경고의 단어 (업데이트)
REMOTE_ADDR
여전히 가장 안정적인 IP 주소 소스를 나타냅니다 . $_SERVER
여기에 언급 된 다른 변수들은 원격 클라이언트에 의해 아주 쉽게 스푸핑 될 수 있습니다. 이 솔루션의 목적은 프록시 뒤에있는 클라이언트의 IP 주소를 확인하는 것입니다. 일반적으로이 주소를 직접 반환 한 IP 주소와 함께 사용하여 $_SERVER['REMOTE_ADDR']
둘 다 저장하는 것을 고려할 수 있습니다 .
이 솔루션은 99.9 %의 사용자에게 완벽하게 적합합니다. 자체 요청 헤더를 주입하여 시스템을 악용하려는 악의적 인 사용자의 0.1 %로부터 사용자를 보호하지는 않습니다. 미션 크리티컬을 위해 IP 주소에 의존하는 경우 REMOTE_ADDR
프록시 뒤에있는 사람들을 수용하고 귀찮게하지 마십시오.