首页 | DV动态 | 数码产品 | 视频采编 | 网站建设 |
【收藏DV】
  最近3月排行
·赤马劫
·985、211、双一流
·上了大学也没体面工作,我们是否还要上大学- 附一组数据
·许小年:碎片化信息让人变得无知,要少看手机多读书
·许小年:浅析日本失去的30年——兼评“资产负债表衰退”
·高中英语-单词表
·常用网管软件下载,持续更新中...
真正的取真实IP地址及利弊
2006/5/5 11:29:25
 

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

stringIpAddress=(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)。

代码如下:

/**////
///取得客户端真实IP。如果有代理则取第一个非内网地址
///
publicstaticstringIPAddress
{
get
{
stringresult=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(inti=0;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.")
{
returntemparyip[i];//找到不是内网的地址
}
}
}
elseif(Text.IsIPAddress(result))//代理即是IP格式
returnresult;
else
result=null;//代理中的内容非IP,取IP
}
}

stringIpAddress=(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;

returnresult;
}
}


取“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地址:

Private Function getIP()

    Dim strIPAddr
    If Request.ServerVariables("HTTP_X_FORWARDED_FOR") = "" OR InStr(Request.ServerVariables("HTTP_X_FORWARDED_FOR"), "unknown") > 0 Then
      strIPAddr = Request.ServerVariables("REMOTE_ADDR")
    ElseIf InStr(Request.ServerVariables("HTTP_X_FORWARDED_FOR"), ",") > 0 Then
      strIPAddr = Mid(Request.ServerVariables("HTTP_X_FORWARDED_FOR"), 1, InStr(Request.ServerVariables("HTTP_X_FORWARDED_FOR"), ",")-1)
    ElseIf InStr(Request.ServerVariables("HTTP_X_FORWARDED_FOR"), ";") > 0 Then
      strIPAddr = Mid(Request.ServerVariables("HTTP_X_FORWARDED_FOR"), 1, InStr(Request.ServerVariables("HTTP_X_FORWARDED_FOR"), ";")-1)
    Else
      strIPAddr = Request.ServerVariables("HTTP_X_FORWARDED_FOR")
    End If
    getIP = Trim(Mid(strIPAddr, 1, 30))
End Function (DVOL本文转自:中国DV传媒 http://www.dvol.cn)

欢迎关注微信公众账号:手机烟台(mYantai)

 

  上一篇:WAP中利用截取手机号码达到自动登入的一段源码
  下一篇:浅谈TeeChart组件在ASP中的应用
      更多...
::打印本页 ::      ::关闭窗口::


版权所有© 数码在线网站 DV OnLine©  鲁ICP备12016322号-1