Adres IP odwiedzającego stronę – PHP

Adres IP odwiedzającego stronę przechowywany jest w zmiennej $_SERVER['REMOTE_ADDR']. Jednak w sytuacji, gdy klient korzysta z serwera proxy w zmiennej tej pojawi się adres IP proxy, a nie klienta. W dużej części przypadków serwer proxy przekazuje adres klienta, można go więc odczytać w PHP.

W PHP adres IP klienta używającego serwera proxy zwykle znajduje się w tablicy $_SERVER pod pozycją HTTP_X_FORWARDED_FOR (dane te są zapisane w następującej postaci: IPclient, IPproxy1, IPproxy2). Jednak niektóre serwery proxy nie przekazują go wcale – dostępny jest jedynie adres serwera. Jeszcze inne przekazują adres klienta w innym nagłówku HTTP. W takim przypadku adres możemy znaleźć w tablicy $_SERVER pod jedną z następujących pozycji: HTTP_CLIENT_IP, HTTP_X_CLUSTER_CLIENT_IP, HTTP_X_FORWARDED, HTTP_FORWARDED_FOR, HTTP_FORWARDED. Natomiast w $_SERVER['HTTP_VIA'] zawarta jest informacja (zwykle jego nazwa) o serwerze proxy.

W celu sprawdzenia wartości tych zmiennych możemy napisać w PHP prosty skrypt:

/**
 * Zwraca w postaci ciągu znaków (nadającego się np. do dołączenia do nagłówka e-maila)
 * informacje o IP klienta przekazane przez serwer proxy w odpowiednich zmiennych
 *
 * @return string
 */
function get_client_info() {
    $info = '';
    foreach ( array('REMOTE_ADDR', 'HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_X_FORWARDED', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'HTTP_VIA') as $key) {
        if (array_key_exists($key, $_SERVER) === true) {
            $info .= $key . ': ' . $_SERVER[$key] . PHP_EOL;
        }
    }
    return $info;
}

Jako wynik działania funkcji zobaczymy np. coś takiego:
REMOTE_ADDR: 84.10.1.42
HTTP_X_FORWARDED_FOR: 70.8.128.16, 127.0.0.1,84.10.1.42
HTTP_VIA: 1.1 (frontal)serwer.profuturo.edu.pl (squid/3.1.19), 1.1 (external)serwer.profuturo.edu.pl (squid/3.1.19)

Gdzie 84.10.1.42 jest adresem IP serwera proxy, natomiast 70.8.128.16 adresem klienta.

Do praktycznego zastosowania można napisać funkcję która zwraca pojedynczy adres IP:

/**
 * Zwraca w postaci ciągu znaków adres IP klienta
 *
 * @return string
 */
function get_ip() {
    foreach (array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_X_FORWARDED', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key) {
        if (array_key_exists($key, $_SERVER) === true) {
            foreach (explode(',', $_SERVER[$key]) as $ip) {
                $ip = trim($ip);
                //sprawdzamy czy zawartość $ip jest adresem IP,
                //nie jest prywatnym adresem IP (IPv4: 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16; IPv6: zaczynające się od FD lub FC)
                //nie jest innym zarezerwowanym zakresem IP (IPv4: 0.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24 i 224.0.0.0/4)
                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {
                    return $ip;
                }
            }
        }
    }
}

Jako wynik działania funkcji zobaczymy adres IP klienta:

Należy mieć na uwadze, że najbardziej wiarygodna jest zawartość $_SERVER['REMOTE_ADDR'], pozostałe wartości mogą być w bardzo prosty sposób ustawione przez użytkownika (chociażby przez instalację wtyczki modyfikującej nagłówki wysyłane do serwera).

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

To prevent spam, URLs are not allowed in comments. All comments are moderated and subject to approval.
Aby zapobiec spamowi, adresy URL nie są dozwolone w komentarzach. Wszystkie komentarze są moderowane i podlegają zatwierdzeniu.