Uzyskanie adresu IP klienta: REMOTE ADDR, HTTP X FORWARDED FOR, co jeszcze może być przydatne?

Rozumiem, że patrzenie na obie te zmienne jest standardową praktyką. Oczywiście można je łatwo sfałszować. Jestem ciekaw, jak często można oczekiwać, że te wartości (zwłaszcza HTTP_X_FORWARDED_FOR) zawierają prawdziwe informacje, a nie tylko są kodowane lub mają ich wartości pozbawione?

Ktoś z doświadczeniem lub statystykami na ten temat?

Czy jest coś jeszcze, co może być przydatne do zadania uzyskania adresu IP klienta?

Author: yzorg, 2009-02-09

6 answers

To zależy od charakteru twojej strony.

Zdarza mi się pracować na oprogramowaniu, w którym śledzenie adresów IP jest ważne, a w polu używanym przez strony parterowe domyślam się, że około 20% - 40% żądań jest wykrywalnie sfałszowanych adresów IP lub nagłówków wygaszonych, w zależności od pory dnia i skąd pochodzą. W przypadku witryny, która pobiera ruch organiczny (tj. nie za pośrednictwem partnerów), spodziewałbym się znacznie wyższego współczynnika dobrych adresów IP.

Jak powiedział Kosi, uważaj co robisz z tym - Adresy IP nie są w żaden sposób wiarygodnym sposobem identyfikacji unikalnych użytkowników.

 27
Author: annakata,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-09 10:41:38

Oprócz REMOTE_ADDR i HTTP_X_FORWARDED_FOR istnieją inne nagłówki, które można ustawić, takie jak:

  • HTTP_CLIENT_IP
  • HTTP_X_FORWARDED_FOR może być rozdzielana przecinkami lista adresów IP
  • HTTP_X_FORWARDED
  • HTTP_X_CLUSTER_CLIENT_IP
  • HTTP_FORWARDED_FOR
  • HTTP_FORWARDED

Znalazłem kod na poniższej stronie przydatny:
http://www.grantburton.com/?p=97

 58
Author: ejunker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-26 18:44:23

Przeniosłem kod PHP Granta Burtona na ASP.Net statyczna metoda wywołana przez HttpRequestBase. Opcjonalnie przeskoczy przez dowolne prywatne zakresy adresów IP.

public static class ClientIP
{
    // based on http://www.grantburton.com/2008/11/30/fix-for-incorrect-ip-addresses-in-wordpress-comments/
    public static string ClientIPFromRequest(this HttpRequestBase request, bool skipPrivate)
    {
        foreach (var item in s_HeaderItems)
        {
            var ipString = request.Headers[item.Key];

        if (String.IsNullOrEmpty(ipString))
            continue;

        if (item.Split)
        {
            foreach (var ip in ipString.Split(','))
                if (ValidIP(ip, skipPrivate))
                    return ip;
        }
        else
        {
            if (ValidIP(ipString, skipPrivate))
                return ipString;
        }
    }

    return request.UserHostAddress;
}

private static bool ValidIP(string ip, bool skipPrivate)
{
    IPAddress ipAddr;

    ip = ip == null ? String.Empty : ip.Trim();

    if (0 == ip.Length
        || false == IPAddress.TryParse(ip, out ipAddr)
        || (ipAddr.AddressFamily != AddressFamily.InterNetwork
            && ipAddr.AddressFamily != AddressFamily.InterNetworkV6))
        return false;

    if (skipPrivate && ipAddr.AddressFamily == AddressFamily.InterNetwork)
    {
        var addr = IpRange.AddrToUInt64(ipAddr);
        foreach (var range in s_PrivateRanges)
        {
            if (range.Encompasses(addr))
                return false;
        }
    }

    return true;
}

/// <summary>
/// Provides a simple class that understands how to parse and
/// compare IP addresses (IPV4) ranges.
/// </summary>
private sealed class IpRange
{
    private readonly UInt64 _start;
    private readonly UInt64 _end;

    public IpRange(string startStr, string endStr)
    {
        _start = ParseToUInt64(startStr);
        _end = ParseToUInt64(endStr);
    }

    public static UInt64 AddrToUInt64(IPAddress ip)
    {
        var ipBytes = ip.GetAddressBytes();
        UInt64 value = 0;

        foreach (var abyte in ipBytes)
        {
            value <<= 8;    // shift
            value += abyte;
        }

        return value;
    }

    public static UInt64 ParseToUInt64(string ipStr)
    {
        var ip = IPAddress.Parse(ipStr);
        return AddrToUInt64(ip);
    }

    public bool Encompasses(UInt64 addrValue)
    {
        return _start <= addrValue && addrValue <= _end;
    }

    public bool Encompasses(IPAddress addr)
    {
        var value = AddrToUInt64(addr);
        return Encompasses(value);
    }
};

private static readonly IpRange[] s_PrivateRanges =
    new IpRange[] { 
            new IpRange("0.0.0.0","2.255.255.255"),
            new IpRange("10.0.0.0","10.255.255.255"),
            new IpRange("127.0.0.0","127.255.255.255"),
            new IpRange("169.254.0.0","169.254.255.255"),
            new IpRange("172.16.0.0","172.31.255.255"),
            new IpRange("192.0.2.0","192.0.2.255"),
            new IpRange("192.168.0.0","192.168.255.255"),
            new IpRange("255.255.255.0","255.255.255.255")
    };


/// <summary>
/// Describes a header item (key) and if it is expected to be 
/// a comma-delimited string
/// </summary>
private sealed class HeaderItem
{
    public readonly string Key;
    public readonly bool Split;

    public HeaderItem(string key, bool split)
    {
        Key = key;
        Split = split;
    }
}

// order is in trust/use order top to bottom
private static readonly HeaderItem[] s_HeaderItems =
    new HeaderItem[] { 
            new HeaderItem("HTTP_CLIENT_IP",false),
            new HeaderItem("HTTP_X_FORWARDED_FOR",true),
            new HeaderItem("HTTP_X_FORWARDED",false),
            new HeaderItem("HTTP_X_CLUSTER_CLIENT_IP",false),
            new HeaderItem("HTTP_FORWARDED_FOR",false),
            new HeaderItem("HTTP_FORWARDED",false),
            new HeaderItem("HTTP_VIA",false),
            new HeaderItem("REMOTE_ADDR",false)
    };
}
 10
Author: IDisposable,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-04 23:21:36

Brak prawdziwej odpowiedzi na twoje pytanie ale:
Generalnie poleganie na adresie IP klientów nie jest moim zdaniem dobrą praktyką, ponieważ nie można identyfikować klientów w unikalny sposób.

Problemy na drodze są takie, że jest sporo scenariuszy, w których IP tak naprawdę nie dopasowuje się do klienta:

  • Proxy / Webfilter (mangle prawie wszystko)
  • sieć anonimowa (tutaj też nie ma szans)
  • nat (wewnętrzny IP nie jest zbyt przydatny dla Ty)
  • ...

Nie mogę zaoferować żadnych statystyk, ile adresów IP jest średnio wiarygodne, ale co mogę powiedzieć, że jest prawie niemożliwe, aby stwierdzić, czy dany adres IP jest prawdziwym adresem klientów.

 7
Author: Kosi2801,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-09 10:28:04

IP + "User Agent" może być lepszym rozwiązaniem dla unikalnych użytkowników.

 2
Author: Mahesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-09 12:02:05

Jeśli jesteś za proxy, należy użyć X-Forwarded-For: http://en.wikipedia.org/wiki/X-Forwarded-For

Jest to projekt standardu IETF z szerokim wsparciem:

Pole X-Forwarded-For jest obsługiwane przez większość serwerów proxy, w tym Squid, Apache mod_proxy, Pound, HAProxy, Varnish cache, IronPort Web Security Appliance, AVANU WebMux, ArrayNetworks, Radware ' s AppDirector and Alteon ADC, ADC-VX, and ADC-VA, F5 Big-IP, Blue Coat ProxySG, Cisco Cache Engine, McAfee Web Gateway, Phion Airlock, Finjan ' s Vital Security, NetApp NetCache, jetNEXUS, Crescendo Sieci Maestro, Web Adjuster i Websense Web Security Gateway.

Jeśli nie, oto kilka innych popularnych nagłówków, które widziałem:

 1
Author: lmsurprenant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-01 19:26:11