2009-02-09 10 views
54

Ich verstehe, dass es eine Standardpraxis ist, diese beiden Variablen zu betrachten. Natürlich können sie leicht gefälscht werden. Ich bin gespannt, wie oft Sie erwarten können, dass diese Werte (insbesondere die HTTP_X_FORWARDED_FOR) echte Informationen enthalten und nicht nur verschlüsselt werden oder ihre Werte entfernt werden?10 Ermitteln der IP-Adresse des Clients: REMOTE_ADDR, HTTP_X_FORWARDED_FOR, was könnte sonst noch nützlich sein?

Jeder mit der Erfahrung oder Statistiken zu diesem Thema?

Gibt es noch etwas, das nützlich sein kann, um die IP-Adresse des Clients zu erhalten?

+0

Beachten Sie, dass die Frage und die Antworten beide das HTTP_-Präfix verwenden, das ein bestimmtes Implementierungsdetail von ASP.NET v1.0-v4.x ist, wenn HTTP-Anforderungsheader zur ServerVariables-Auflistung hinzugefügt werden. Ein anderes Beispiel ist REMOTE_ADDR, das in ASP.NET Core über eine eigene API verfügt. https://stackoverflow.com/questions/28664686/how-do-i-get-client-ip-address-in-asp-net-core – yzorg

Antwort

26

Es hängt von der Art Ihrer Website ab.

Ich arbeite zufällig an ein wenig Software, wo IP-Tracking wichtig ist, und innerhalb eines Feldes von Parter-Sites denke ich, dass etwa 20% - 40% der Anfragen entweder detektierbar gefälschte IPs oder ausgeblendete Header sind zu der Tageszeit und woher sie kamen. Für eine Seite, die organischen Traffic bekommt (d. H. Nicht über Partner), würde ich ein viel höheres Verhältnis von guten IPs erwarten.

Wie Kosi sagte, seien Sie vorsichtig, was Sie damit tun - IPs sind in keiner Weise eine zuverlässige Möglichkeit, eindeutige Besucher zu identifizieren.

7

Keine echte Antwort auf Ihre Frage aber:
Im Allgemeinen auf die IP-Adresse des Clients zu verlassen ist meiner Meinung nach keine gute Praxis, da es nicht nutzbar ist, um Kunden auf einzigartige Weise zu identifizieren.

Probleme auf der Straße sind, dass es ziemlich viele Szenarien, in denen die IP nicht wirklich an einen Kunden auszurichten:

  • Proxy/Webfilter (mangle fast alles)
  • Anonymizer Netzwerk (keine Chance hier entweder)
  • NAT (eine interne IP ist nicht sehr nützlich für Sie)
  • ...

ich nicht bieten kann y Statistiken über wie viele IP-Adressen sind im Durchschnitt zuverlässig, aber was ich Ihnen sagen kann, dass es fast unmöglich zu sagen, ob eine bestimmte IP-Adresse ist die echte Client-Adresse.

+0

Was ist "Best Practices", um * Kunden auf einzigartige Weise zu identifizieren *? *** Checkliste ***: _Nicht Clients verwenden IP address_ – Kiquenet

2

IP + "User Agent" könnte ein besserer für den einzelnen Besucher sein.

+0

nah, Benutzer-Agenten sind nicht sehr vielfältig und weit gespooft sowieso – annakata

+5

weit gefälscht, aber im Allgemeinen ändern sie nicht von Anfrage zu Anfrage - http: //panopticlick.eff .org/ – wprl

55

Neben REMOTE_ADDR und HTTP_X_FORWARDED_FOR gibt es einige andere Header, die wie festgelegt werden können:

  • HTTP_CLIENT_IP
  • HTTP_X_FORWARDED_FOR können durch Komma getrennte Liste von IP-Adressen sein
  • HTTP_X_FORWARDED
  • HTTP_X_CLUSTER_CLIENT_IP
  • HTTP_FORWARDED_FOR
  • HTTP_FORWARDED

fand ich den Code auf der folgenden Seite nützlich:
http://www.grantburton.com/?p=97

+0

Ist diese Liste irgendwie vollständig, dh deckt sie über 90% aller Proxies ab? – basZero

+4

Ich glaube nicht, dass diese Header das Präfix HTTP_ haben sollten ... ein wenig Suche nach oben http://stackoverflow.com/questions/3834083/http-headers-what-is-the-difference-between-x-forwarded -for-x-forwarded-for-a – lmsurprenant

+0

Es gibt auch einen Referer jetzt, nach [RFC 7239] (https://tools.ietf.org/html/rfc7239) – Kevin

10

Ich habe portiert PHP-Code Grant Burton auf eine ASP.Net statische Methode aufrufbar gegen die Httprequestbase. Es wird optional private IP-Bereiche überspringen.

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) 
    }; 
} 
+2

Danke für den Code. Es gibt jedoch ein paar Probleme damit.Zuerst gibt es ein zusätzliches 'return false;' in 'ValidIP'. Zweitens behandelt die IPRange-Klasse IPV6 nicht wirklich, da IPV6-Adressen 128 Bits sind. Vielleicht könnte 'System.Numerics.BigInteger' von .NET 4 verwendet werden, aber es ist auch möglich, dass private Bereiche mit IPV6 ohnehin weniger interessant sind (?). –

+1

Oh, und ein anderes Problem: Anstatt Header von request.Headers zu überprüfen, denke ich, dass Sie request.ServerVariables wollen. Letzteres hat Schlüssel wie 'HTTP_X_FORWARDED_FOR', während ersteres nur' X-Forwarded-For' wäre. –

+0

Wäre toll, wenn dies auch unterstützt [RFC 7239] (https://tools.ietf.org/html/rfc7239): D – Kevin

1

Wenn Sie hinter einem Proxy sind, sollten Sie X-Forwarded-For verwenden: http://en.wikipedia.org/wiki/X-Forwarded-For

Es ist ein IETF draft standard mit breiter Unterstützung ist:

Der X-Forwarded-For-Feld von den meisten unterstützt wird Proxy-Server, einschließlich Squid, Apache mod_proxy, Pfund, HAProxy, Varish Cache, IronPort Web-Sicherheits-Appliance, AVANU WebMux, ArrayNetworks, Radware AppDirector und Alteon ADC, ADC-VX, a nd ADC-VA, F5 Groß-IP, Blue Coat ProxySG, Cisco Cache Engine, McAfee Web Gateway, Phion Airlock, Finjans lebenswichtige Sicherheit, NetApp NetCache, jetNEXUS, Crescendo Netzwerke Maestro, Web Adjuster und Websense Web Security Gateway.

Wenn nicht, hier sind ein paar andere gemeinsame Header ich gesehen habe: