获得真实IP地址及分析 (asp.net C#)

C#进阶-基于.NET Framework 4.x框架实现ASP.NET WebForms项目IP拦截器 在这篇文章中,我们将探讨如何在 `ASP.NET WebForms` 中实现IP拦截器,以便在 `ASMX Web 服务方法` 和 `HTTP 请求` 中根据IP地址进行访问控制。我们将使用自定义的 `SoapExtension` 和 `IHttpModule` 来实现这一功能,并根据常用的两种文本传输协议:`SOAP协议` 和 `HTTP协议`进行分别讲解。 阅读详情
目前网上流行的所谓“取真实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。如果有代理则取第一个非内网地址
/// </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格式检查也是不可少的。

附: (Text是我自定义的一个类,IsIPAddress是其中的一个判断是否是IP地址格式的方法)
#region bool IsIPAddress(str1) 判断是否是IP格式
/**//// <summary>
/// 判断是否是IP地址格式 0.0.0.0
/// </summary>
/// <param name="str1">待判断的IP地址</param>
/// <returns>true or false</returns>

public static bool IsIPAddress(string str1)
{
    if(str1==null||str1==string.Empty||str1.Length<7||str1.Length>15) return false;

    string regformat = @"^/d{1,3}[/.]/d{1,3}[/.]/d{1,3}[/.]/d{1,3}$";

    Regex regex = new Regex(regformat,RegexOptions.IgnoreCase );
    return regex.IsMatch(str1);
}
#endregion

ASP.NET获取客户端真实IP地址的完整实现方案 你以为加个白名单就够了?Too young.你以为学会了就够了吗?远远不够。真实的战场充满欺骗、伪装和不确定性。今天的最佳实践,明天可能就成了漏洞源头。所以,请记住这几条铁律:永远不要盲目信任任何头部字段建立自己的可信代理拓扑图每层都要有降级和监控合规不是附加项,而是设计前提最终你会发现,真正难的从来不是技术实现,而是在性能、准确性、安全性与合规性之间找到平衡点。而这,正是优秀工程师的价值所在。✨本文还有配套的精品资源,点击获取 阅读详情

相关推荐

ASP如何获取真实IP地址

ASP如何获取真实IP地址 大家都知道,在ASP中可以使用Request.ServerVariables("REMOTE_ADDR")来取得客户端的IP地址,但如果客户端是使用代理服务器来访问,那取到的就是代理服务器的IP地址,而不是真正的客户端IP地址。要想透过代理服务器取得客户端的真实IP地址,就要使用Request.ServerVariables("HTTP_X_FORWARDED_FOR")来读取。   不过要注意的是,并不是每个代理服务器都能用Request.ServerVariables("HTTP_X_FORWARDED_FOR")来读取客户端的真实 IP,有些用此方法读取到的仍然是代理服务器的 IP。   还有一点需要注意的是:如果客户端没有通过代理服务器来访问,那么用Request.ServerVariables ("HTTP_X_FORWARDED_FOR")取到的值将是空的。因此,如果要在程序中使用此方法,可以这样处理:   ......   userip = Request.ServerVariables("HTTP_X_FORWARDED_FOR")   If userip = "" Then userip = Request.ServerVariables("REMOTE_ADDR")   ......   即:如果客户端通过代理服务器,则取HTTP_X_FORWARDED_FOR的值,如果没通过代理服务器,就取 REMOTE_ADDR的值。

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

本文实例讲述了C#获取真实IP地址实现方法,分享给大家供大家参考。具体实现方法如下: 通常来说,大家获取用户IP地址常用的方法是: 代码如下:string IpAddress = “”; if((HttpContext.Current.Request.ServerVariables[“HTTP_X_FORWARDED_FOR”]!=null && HttpContext.Current.Request.ServerVariables[“HTTP_X_FORWARDED_FOR”] !=String.Empty) ) {         IpAddress=HttpContext.Curre

c# 取客户端真实IP

c# 取客户端真实IP类 方法: Public String GetClientIP(HttpContext con) { ... } Public String GetLocalIP() { ... }

.NET ASP.NET URL地址栏详解

一: URL举例 就以下面这个URL为例,介绍下普通URL的各部分组成 http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name 从上面的URL可以看出,一个完整的URL包括以下几部分: (1)协议部分: 该URL的协议部分为“http:”,这代表网页使用的是HTTP协议。在Internet...

weixin_44870681的博客 1104

ASP.NET获取真正的客户端IP地址的6种方法

ASP中使用 Request.ServerVariables("REMOTE_ADDR") 来取得客户端的IP地址,但如果客户端是使用代理服务器来访问,那取到的就是代理服务器的IP地址,而不是真正的客户端IP地址。 要想透过代理服务器取得客户端的真实IP地址,就要使用 Request.ServerVariables("HTTP_X_FORWARDED_FOR") 来读取。 不过要注意的事,并不是每个代理服务器都能用 Request.ServerVariables("HTTP_X_FORWA...

xwnxwn的专栏 3367

Asp.net获取用户真实Ip地址

[code="c#"] /// /// 获取远程访问用户的Ip地址 /// /// 返回Ip地址 protected string GetLoginIp() { string loginip = ""; //Request.ServerVariable...

Cool_xiaocao的专栏 643

网络安全-真实ip获取&伪造与隐藏&挖掘

proxy protocol没有研究,和TOA差不多,按照协议发包就行了,实现就交给读者吧。TOA的伪造方式还是不错的,非linux下没有btftools,可以自己写一个代理,把浏览器的流量转发到本地代理,代理的功能就是把TOA改一下。一些代理隐藏ip还是不错的,除非网站从开始没有使用cdn、部分使用cdn,或网站服务器有其他服务导致真实ip发出包了。该博客作者我也问了,一开始就使用了CDN,也没有其他子域名、服务,应该是无法找到真实IP了。

关注网络安全、云原生安全 6137

asp.net 实现ip记录

  在ASP中使用 Request.ServerVariables("REMOTE_ADDR") 来取得客户端的IP地址,但如果客户端是使用代理服务器来访问,那取到的就是代理服务器的IP地址,而不是真正的客户端IP地址。要想透过代理服务器取得客户端的真实IP地址,就要使用 Request.ServerVariables("HTTP_X_FORWARDED_FOR")

aimcode 1226

C#获取真实IP地址分析

上篇文章提到的“asp.net获取IP问题”里的方法,都有bug,没有考虑到多层透明代理的情况。代码:string IpAddress = (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]!=null            &amp;&amp; HttpContext.Current.Request.Serve...

烟花尽散的博客 1031

ASP.NET获取客户端IP及MAC地址

 获取客户端IP:private string GetClientIP()  {   string result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];   if (null == result || result == String.Empty)   {    result = HttpCo

jxufewbt的专栏 7027

C#(asp.net)读取yodao提供的ip地址库接口查询IP地址

有道(yodao)提供了IP地址查询接口,我们就采用有道(yodao)提供的IP地址查询接口详细讲解,用C#(asp.net)调用。         有道(yodao)提供的接口返回给我们是xml格式的文件,在IE中输入网址:http://www.youdao.com/smartresult-xml/search.s?type=ip&q=59.58.2.171,得到的格式文件就是:

home9012的专栏 854

asp.net获取真实ip的方法

主要介绍了asp.net获取真实ip的方法,通过一个简单的自定义函数达到获取用户真实IP的功能,非常简单实用,需要的朋友可以参考下

VS2019上用C#ASP.NET写WebForm网页的试练

1 前言 NET平台的VS2019还是挺爽手的IDE,写WinForm较写WebForm程序写起来方便,毕竟项目所需资源基本上都在本地,而WinForm不仅需要IIS支持,还需要其它Script帮助。所说MS出了ASP5,微软自己用的网络平台是基于.NETASP5的。MS能跑在.NETASP上,其它小网站当然不在话下。其实VS2019上,有MVC模式可参选,但初步印象好像不是Ruby on Rail那样的MVC实例化了。先搭个WebForm找找感觉,如果能激发出足够的热情,后面的事就好开展了。 2

weixin_45707491的博客 1万+

ASP.NET如何判断IP地址是否在某个IP的范围内实例

ASP.NET如何判断IP地址是否在某个IP的范围内实例

u013334925的博客 845

C# Asp.net获取用户外网真实Ip地址

/// <summary> /// 获取远程访问用户的Ip地址 /// </summary> /// <returns>返回Ip地址</returns> protected string GetLoginIp() { st...

小熊猫 1129

JS、C#ASP.NET获取用户客户端ip地址,Mac地址,端口号、主机名案例详解。

首先声明,出于安全,JS、C#(ASP.NET)是无法获取到客户端的Mac地址和端口号的,以下方法可以获取到客户端的公网ip地址和内网ip地址: 1、页面引用第三方JS接口,适用所有平台及浏览器,代码及截图如下: <html> <head> <meta http-equiv="Content-Type" content="text/html; charse...

慢谈人生 1077
上一篇: Bind和Eval的不同用法 (asp.net C#)
下一篇: Ajax 基础 (asp.net C#)
bentonite
博客等级 码龄17年 1粉丝 2原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值