Obtener la dirección IP del cliente: REMOTE_ADDR, HTTP_X_FORWARDED_FOR, ¿qué otra cosa podría ser útil?

StackOverflow https://stackoverflow.com/questions/527638

Pregunta

entiendo que es una práctica estándar para mirar estas dos variables. Por supuesto que fácilmente pueden ser falseadas. Soy curioso con qué frecuencia se puede esperar de estos valores (especialmente el HTTP_X_FORWARDED_FOR) para contener la información genuina y no sólo ser revueltos o tienen sus valores despojados?

Cualquier persona con la experiencia o las estadísticas en esta materia?

¿Hay algo más que pueda ser útil para la tarea de obtener la dirección IP del cliente?

¿Fue útil?

Solución

Depende de la naturaleza de su sitio.

yo trabajo en un poco de software de seguimiento de IP, donde es importante, y dentro de un campo consumida por los sitios parter supongo que alrededor de 20% - IPs o encabezados 40% de las solicitudes están ya sea de forma detectable suplantar blanqueó a cabo, en función de la hora del día y de dónde venían. Para un sitio que recibe el tráfico orgánico (es decir, no a través de socios) que cabe esperar una proporción mucho más alta de buenas direcciones IP.

Como dijo Kosi, tener cuidado con lo que estás haciendo con esto -. IPs son de ninguna manera una forma fiable de identificar a los visitantes únicos

Otros consejos

Además de REMOTE_ADDR y HTTP_X_FORWARDED_FOR hay algunas otras cabeceras que se pueden configurar, tales como:

  • HTTP_CLIENT_IP
  • HTTP_X_FORWARDED_FOR puede comas lista de IPs delimitado
  • HTTP_X_FORWARDED
  • HTTP_X_CLUSTER_CLIENT_IP
  • HTTP_FORWARDED_FOR
  • HTTP_FORWARDED

He encontrado el código en el siguiente sitio útil:
http://www.grantburton.com/?p=97

He portado código PHP de subvención Burton a un método estático ASP.Net exigible en contra de la HttpRequestBase. Se omitirá opcionalmente a través de cualquier rango IP privada.

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

Sin respuesta real a su pregunta, pero:
Generalmente depender de los clientes dirección IP es en mi opinión no es una buena práctica, ya que no se puede utilizar para identificar a los clientes de una manera única.

Los problemas en la carretera son que hay bastantes escenarios donde la IP en realidad no se alinean a un cliente:

  • Proxy / Webfilter (mangle casi todo)
  • red Anonymizer (sin oportunidad aquí tampoco)
  • NAT (una IP interna no es muy útil para usted)
  • ...

No puedo ofrecer ninguna estadística sobre el número de direcciones IP son en promedio confiable, pero lo que puedo decir que es casi imposible saber si una determinada dirección IP es los clientes reales de direcciones.

IP + "agente de usuario" podría ser un mejor de visitante único.

Si estás detrás de un proxy, debe utilizar X-Forwarded-For: http: // en .wikipedia.org / wiki / X-reenvía Para

Es un IETF proyecto estándar con un amplio apoyo:

  

El X-reenviado-For campo está soportado por la mayoría de servidores proxy,   incluyendo calamar, Apache mod_proxy, Libra, HAProxy, caché de barniz,   IronPort Web Security Appliance, AVANU WebMux, ArrayNetworks,   AppDirector de Radware Alteon y ADC, ADC-VX, y ADC-VA, F5 BIG-IP,   Blue Coat ProxySG, Cisco caché del motor, McAfee Web Gateway, Phion   Esclusa de aire, Vital seguridad de Finjan, NetApp NetCache, jetNEXUS, Crescendo   Redes Maestro, Ajustador Web y Websense Web Security Gateway.

Si no es así, aquí hay un par de otras cabeceras comunes que he visto:

A continuación llamar al método de acción desde el archivo JS (Para obtener la dirección IP IPv4).

    [HttpGet]
    public string GetIP()
    {
        IPAddress[] ipv4Addresses = Array.FindAll(
            Dns.GetHostEntry(string.Empty).AddressList,
            a => a.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
        return ipv4Addresses.ToString();
    }

Comprobar después de mantener el punto de interrupción, y el uso como por su exigencia. Su funcionamiento muy bien para mí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top