获取客户端IP地址:REMOTE_ADDR,HTTP_X_FORWARDED_FOR,还有什么可用的?

我知道这是一个标准的做法,看看这两个variables。 当然,他们很容易被欺骗。 我很好奇你能期望这些值(特别是HTTP_X_FORWARDED_FOR )能包含真正的信息,而不是被HTTP_X_FORWARDED_FOR或者被剥夺价值?

任何有这方面经验或统计的人?

还有什么可以帮助获取客户端的IP地址吗?

这取决于你的网站的性质。

我碰巧在一些IP跟踪很重要的软件上工作,并且在一个由参与者站点占用的领域内,我猜测有20%到40%的请求是可检测到的IP地址或者标题消失,这取决于一天,他们从哪里来。 对于获得有机stream量的网站(即不通过合作伙伴),我希望有更好的IP比例。

正如Kosi所说,要小心你在做什么 – IPs绝不是一个可靠的方式来识别独特的访问者。

REMOTE_ADDRHTTP_X_FORWARDED_FOR还有一些其他标题可以设置,如:

  • HTTP_CLIENT_IP
  • HTTP_X_FORWARDED_FOR可以是逗号分隔的IP列表
  • HTTP_X_FORWARDED
  • HTTP_X_CLUSTER_CLIENT_IP
  • HTTP_FORWARDED_FOR
  • HTTP_FORWARDED

我发现以下网站上的代码很有用:
http://www.grantburton.com/?p=97

我已经把Grant Burton的PHP代码移植到一个可以调用HttpRequestBase的ASP.Net静态方法中。 它可以select跳过任何专用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地址在我看来不是一个好的做法,因为它不能用于以独特的方式识别客户端。

在路上的问题是,有相当多的情况下,知识产权并不真正对准客户:

  • 代理/ Webfilter(几乎所有的事情)
  • 匿名networking(这里也没有机会)
  • NAT(内部IP对你不是很有用)

我无法提供有关平均有多lessIP地址可靠的统计信息,但是我可以告诉您,几乎不可能知道给定的IP地址是否是真正的客户端地址。

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

如果你在代理之后,你应该使用X-Forwarded-For : http : //en.wikipedia.org/wiki/X-Forwarded-For

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

包括Squid,Apache mod_proxy,Pound,HAProxy,Varnishcaching,IronPortnetworking安全设备,AVANU WebMux,ArrayNetworks,Radware的AppDirector和Alteon ADC,ADC-VX以及ADC-VX等大多数代理服务器都支持X-Forwarded- VA,F5 Big-IP,Blue Coat ProxySG,Cisco Cache Engine,McAfee Web Gateway,Phion Airlock,Finjan的重要安全性,NetApp NetCache,jetNEXUS,Crescendo Networks的Maestro,Web Adjuster和Websense Web安全网关。

如果没有,这里有一些我见过的其他常见标题:

  • X-Client-IP( Apache )
  • X-Real-IP( Nginx )