`
jspengxue
  • 浏览: 180995 次
  • 性别: Icon_minigender_1
  • 来自: 天堂和地狱的中间
社区版块
存档分类
最新评论

真正的取真实IP地址及利弊

阅读更多
目前网上流行的所谓"取真实IP地址"的方法,都有bug,没有考虑到多层透明代理的情况。
多数代码类似:
 string IpAddress = (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]!=null
             && HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] !=String.Empty)
             ?HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]
             :HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
事实上,上面的代码只试用与用户只使用了1层代理,如果用户有2层,3层
HTTP_X_FORWARDED_FOR 的值是:"本机真实IP,1层代理IP,2层代理IP,....." ,如果这个时候你的数据中保存IP字段的长度很小(15个字节),数据库就报错了。
实际应用中,因为使用多层透明代理的情况比较少,所以这种用户并不多。
其他应用情况,现在越来越多的网站使用了代理加速方式,比如 新浪、SOHU的新闻 都使用Squid做代理方式,利用多台服务器分流。Squid本身类似透明代理,会发送"HTTP_X_FORWARDED_FOR" ,HTTP_X_FORWARDED_FOR 中包括客户的IP地址,如果此时客户已经使用了一层透明代理,那么程序取的 "HTTP_X_FORWARDED_FOR" 就包括两个IP地址。(我遇到过3个IP地址的情况,4个的未遇到过)
所以取"真正"IP地址的方式,还应该判断  "HTTP_X_FORWARDED_FOR"  中是否有","逗号,或者长度是否超长(超过15字节 xxx.xxx.xxx.xxx)。
所以代码应该如下:

  /// <summary>
 /// 取得客户端真实IP。如果有代理则取第一个非内网地址
 /// by flower.b
 /// </summary>
 public static string IPAddress
   {
     get
       {
         string result = String.Empty;

         result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
         if(result!=null&&result!= String.Empty)
           {
             //可能有代理
             if(result.IndexOf(".")==-1)    //没有"."肯定是非IPv4格式
                 result = null;
             else
               {
                 if(result.IndexOf(",")!=-1)
                   {
                     //有",",估计多个代理。取第一个不是内网的IP。
                     result = result.Replace(" ","").Replace("","");
                     string[] temparyip = result.Split(",;".ToCharArray());
                     for(int i=0;i<temparyip.Length;i++)
                       {
                         if( Text.IsIPAddress(temparyip[i])
                             && temparyip[i].Substring(0,3)!="10."
                             && temparyip[i].Substring(0,7)!="192.168"
                             && temparyip[i].Substring(0,7)!="172.16.")
                           {
                             return temparyip[i];    //找到不是内网的地址
                         }
                     }
                 }
                 else if(Text.IsIPAddress(result)) //代理即是IP格式
                     return result;
                 else
                     result = null;    //代理中的内容 非IP,取IP
             }

         }

         string IpAddress = (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]!=null && HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] !=String.Empty)?HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]:HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

 

         if (null == result || result == String.Empty)
             result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

         if (result == null || result == String.Empty)
             result = HttpContext.Current.Request.UserHostAddress;

         return result;
     }
 }


取"HTTP_X_FORWARDED_FOR" 的弊端。
HTTP_X_FORWARDED_FOR 是HTTP协议中头的一部分,不影响TCP的通讯。也就是说实际上客户端可以发送任意内容的 HTTP_X_FORWARDED_FOR,以就是伪造IP。最简单的是WEB程序的IP记录,本来是要记录真实IP的,反而被"黑客"欺骗。当你的应用程序记录客户的访问IP、拒绝或允许部分IP的访问、错误日志 都会出错,甚至误杀。
因此必要的安全日志应该记录 完整的 "HTTP_X_FORWARDED_FOR" (至少给数据库中的字段分配 3*15+2 个字节,以记录至少3个IP) 和 "REMOTE_ADDR"。对 HTTP_X_FORWARDED_FOR 的IP格式检查也是不可少的。

分享到:
评论

相关推荐

    易语言取本机所有IP地址

    "易语言取本机所有IP地址"是一个针对易语言(EasyLanguage)编程环境的特定功能,旨在帮助开发者获取计算机上所有网络接口的IP地址信息。下面将详细阐述相关知识点。 1. **易语言**:易语言是一种面向对象的、中国...

    真正的获取客户端真实IP地址及利弊分析

    目前网上流行的所谓“取真实IP地址”的方法,都有bug,没有考虑到多层透明代理的情况。

    Java获取客户端真实IP地址

    ### Java获取客户端真实IP地址详解 在Web开发中,获取客户端的真实IP地址是一个常见的需求,尤其是在需要进行地理位置定位、安全审计、流量统计等场景下。然而,在存在反向代理服务器的环境中,传统的`request....

    获取用户真实IP地址,不使用request.getRemoteAddr()的原因是有可能用户使用了代理软件方式避免真实IP地址

    获取请求接口的真实ip 地址工具类。适合所有Java开发人员。针对接口的ip 地址的获取。

    获取访问者真实的IP地址

    此时取第一个IP地址作为客户端的真实IP地址。 3. **处理 `REMOTE_ADDR`**:如果以上两种方式都无法获取到有效的IP地址,则直接使用`request.getRemoteAddr()`方法获取客户端IP地址。需要注意的是,这种方式获取的...

    ASP如何获取真实IP地址

    ### ASP如何获取真实IP地址 在ASP(Active Server Pages)编程环境中,开发人员经常会遇到一个需求:需要准确地获取客户端的真实IP地址。然而,在实际应用中,由于许多用户可能通过代理服务器来访问网站,这就导致...

    易语言十种获取外网IP地址的方法源码,易语言获取外网IP地址五种

    易语言取外网IP地址源码,取外网IP地址

    获取用户真实IP地址

    本篇文章将详细介绍如何在不同情况下获取用户的真实IP地址,并探讨可能遇到的问题。 首先,最常见的方法是在HTTP请求头中查找“X-Real-IP”或“X-Forwarded-For”字段。这些字段通常由代理服务器设置,用于传递原始...

    易语言模块取IP地址.rar

    在本压缩包“易语言模块取IP地址.rar”中,主要包含的是一个专门用于获取IP地址的易语言模块。 模块在编程中通常是一组相关的函数或方法的集合,可以被其他程序调用,以实现特定的功能。在这个“模块取IP地址”中,...

    java IP地址工具类,java IP地址获取,java获取客户端IP地址

    2. **获取客户端IP地址**:在Web应用中,服务器需要区分每个客户端,`IpUtils`可能会有方法处理`HttpServletRequest`对象,从HTTP请求头(如`X-Forwarded-For`或`RemoteAddr`)中解析出真实客户端的IP地址。...

    隐藏真实ip地址的软件

    隐藏真实ip地址的软件

    第六节 收集真实IP地址信息-01

    收集真实IP地址信息 在网络安全中,收集真实IP地址信息是非常重要的一步。因为在很多情况下,网站或应用程序会使用CDN(Content Delivery Network,内容分发网络)来加速用户访问和保护服务器免受攻击。但是,在...

    用Java来获取访问者真实的IP地址

    ### 使用Java获取访问者真实IP地址 在现代Web开发中,获取客户端的真实IP地址是非常重要的。这不仅有助于网站统计分析,还可以用于安全控制、地域限制等功能。然而,在使用如Apache、Squid等反向代理服务器的情况下...

    PB11.5获取IP地址及主机名

    在PowerBuilder 11.5(PB11.5)中获取IP地址和主机名是应用程序与网络通信的基础。这通常涉及到系统编程和网络API的使用。以下是对这个主题的详细解释。 首先,我们需要理解IP地址和主机名的概念。IP地址(Internet...

    规划局域网ip地址实验报告.doc

    计算机网络实验报告 - IP 地址与网络参数的设置及应用 在计算机网络中,IP 地址是网络通信的基础,正确地设置 IP 地址是网络通信的前提。IP 地址是由网络号和主机号组成的,网络号用于标识网络,主机号用于标识主机...

    IP地址HTTP请求工具类

    获取本地IP地址,获取本地Host名称,获取Linux下的IP地址,获取用户真实IP地址,get/post请求 相应的工具类

    java非常强的获取客户端真实IP的两种方法

    需要注意的是,当通过多级反向代理时,`X-Forwarded-For`的值可能会包含多个IP地址,这些IP地址按照顺序排列,通常第一个非unknown的有效IP地址就是客户端的真实IP。 #### 三、获取真实IP的第二种方法 在某些情况...

    C#获取真实IP地址实现方法

    首先,当用户通过Web服务器访问应用程序时,服务器可能会接收到多个IP地址,这取决于用户是否使用了代理服务器。最简单的获取IP地址的方法是通过`HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]`,但...

    IP地址库(Excel版)

    IP地址库(Excel版)是网络管理、数据分析和网络安全领域常用的一种工具,它包含了大量IP地址及其对应的地理位置信息。这份数据库截至2008年10月19日是最新的,意味着它可能不包含后来分配的IP地址或者更新的数据。在...

Global site tag (gtag.js) - Google Analytics