我理解这是一个标准的实践来看,这两个变量。当然他们可以很容易能欺骗。我好奇的是如何往往能期望这些价值(特别是 HTTP_X_FORWARDED_FOR)含有真正的信息并不仅仅是被炒,或者有他们的价值观剥离?

任何人都有经验或统计数据上的这些东西?

是否还有其他可用于任务越来越客户的IP地址吗?

有帮助吗?

解决方案

这要看你的网站的性质。

我正好对位的软件,其中IP跟踪是非常重要的工作,和舞伴网站消费的领域内我猜约20% - 请求的40%要么检测伪造IP地址或标题显示为空白,这取决于一天的时间,他们是从哪里来的。为它获取有机业务(即不通过合作伙伴)的位点,我期望良好的IP的高得多的比率。

随着戈西说,小心你这个做什么 - IP地址是没有办法识别唯一访问者的可靠方法

其他提示

除了 REMOTE_ADDRHTTP_X_FORWARDED_FOR 还有一些其他标题,可以这样设置的:

  • HTTP_CLIENT_IP
  • HTTP_X_FORWARDED_FOR 可逗号分隔的列表IPs
  • HTTP_X_FORWARDED
  • HTTP_X_CLUSTER_CLIENT_IP
  • HTTP_FORWARDED_FOR
  • HTTP_FORWARDED

我找到代码在以下网站有用的:
http://www.grantburton.com/?p=97

我已经转移了格兰特·波顿的PHP代码来对HttpRequestBase调用一个ASP.Net静态方法。它将通过任何私有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)
    };
}

没有真正回答你的问题,但是:
一般依靠客户的IP地址是在我看来不是一个好的做法,因为它不是用来识别客户在一个独特的方式。

问题的道路上,有相当多的情况IP不会真的调整到一个客户:

  • 代理/Webfilter(轧几乎所有的东西)
  • 匿名者网络(没有机会在这里)
  • NAT(一个内部知识产权是不是对你非常有用)
  • ...

我不能提供任何统计数据如何许多的IP地址 平均 可靠的,但我可以告诉你,这几乎是不可能告诉我们,如果IP地址是真实客户的地址。

IP + “用户代理” 可能是一个更好的为唯一访问者。

如果你们背后的代理,应使用 X-Forwarded-For: http://en.wikipedia.org/wiki/X-Forwarded-For

它是一个 IETF标准草案 与广泛的支持:

X-转发领域是支持通过大多数代理服务器 包括鱿鱼,Apache mod_proxy、英镑、代理、清漆缓存, 的网安全设备,AVANU WebMux,ArrayNetworks, Radware的AppDirector和Alteon ADC,ADC-VX和ADC-VA、F5大IP, 蓝色外套ProxySG设备、思科缓引擎,迈克菲网网关,Phion 气闸,Finjan公司是至关重要的安全据NetCache,jetNEXUS,渐强 网络的大师,网调节器和Websense网络安全网关。

如果不是,这里有几个其他常见的头我看到:

从您的JS文件调用下面动作方法(要获得IPv4的IP地址)。

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

检查保持断点后,并根据您的要求使用。 它的工作对我罚款。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top