如何防止恶意带宽 - 吸血鬼请求滥用Azure CDN带宽?

Azu*_*Dev 5 azure azure-cdn

只是为了让人们知道,我确实按照一些人的建议稍微编辑了这个帖子,这个问题已经发布在Azure CDN论坛上.我在StackOverflow上发布它的原因是尝试吸引更多的受众,希望处理相同/类似问题的人可以提供有价值的解决方案/反馈.据我所知,目前还没有解决这个问题的办法,但这会影响任何使用CDN传递内容的企业.我愿意进一步编辑这个问题,但我要问的是,人们不会简单地对这个问题进行投票,因为这听起来像是一个"咆哮",它不是,我可以向你保证它会影响成千上万的企业无论他们是否意识到这一点,每年都要花费数千美元.

所以情况就是这样.假设我正在建立一个图片库网站,我想使用Azure CDN为我提供我的内容.在后端,Azure CDN将从Azure存储帐户中提取内容.CDN速度快,功能强大,但看起来虽然在防止有人能够大量提取内容并因此给用户留下巨大的带宽费用方面有点不安全.让我展示一下我的意思.

因此,昨晚我决定编写一个简单的控制台应用程序,将我的未来的简单图像下载到图片库网站,在for {}循环中,代码如下:

namespace RefererSpoofer
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpWebRequest myHttpWebRequest = null;
            HttpWebResponse myHttpWebResponse = null;

            for (int x = 0; x < 1000; x++)
            {
                string myUri = "http://myazurecdnendpoint.azureedge.net/mystoragecontainer/DSC00580_1536x1152.jpg";
                myHttpWebRequest = (HttpWebRequest) WebRequest.Create(myUri);
                myHttpWebRequest.Referer = "www.mywebsite.com";

                myHttpWebResponse = (HttpWebResponse) myHttpWebRequest.GetResponse();

                Stream response = myHttpWebResponse.GetResponseStream();
                StreamReader streamReader = new StreamReader(response);

                Image image = Image.FromStream(streamReader.BaseStream);

                image.Save(string.Format("D:\\Downloads\\image{0}.Jpeg", x), ImageFormat.Jpeg);

                myHttpWebResponse.Close();
            }

            Console.ReadKey();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

此控制台应用程序对我的Azure CDN端点上托管的映像文件发出1000个超快速连续请求,并将它们保存到我的PC上的"D:\ Downloads"文件夹中,每个文件名对应于for {}循环迭代,即image1.jpeg,image2.jpeg等

刚刚发生了什么?在大约1分钟的时间里,我花了140MB的带宽.这是一款高级CDN,价格为0.17美元/ GB,让我们一起做数学:0.14GB*60分钟*24小时*30天*0.17cents/GB = 1028.16美元的带宽成本,如果有人(例如竞争对手)想做一个单个图像请求持续一个月的时间来危害我的网站.我想你们可以看到我要去哪里...我的网站将有数千张图片,高分辨率,顺便说一下,我在这个例子中使用的图像只有140KB大小.这些类型的请求可以来自匿名代理等.

所以我的问题是:有什么可以阻止某人滥用公开暴露的CDN端点?显然,不能因为恶意请求而支付5000美元,20,000美元的带宽.

现在,Azure Premium CDN具有高级规则引擎,可以根据Referer过滤掉请求,并在Referer与您的网站不匹配时响应403错误.但是,Referer可以伪造,就像我在上面的代码示例中所做的那样,并且CDN仍然允许请求被提供(我使用Referer欺骗测试).这很糟糕,很多人使用Refer来防止'hotlinking',但在这种带宽滥用的情况下,如果Referer可以伪造一行代码,那有什么关系呢?

关于防止此类滥用和巨大的带宽成本,我有过几个想法:

*这两种解决方案都需要CDN采取行动:

  1. 当内容请求到CDN时,CDN可以调用客户端服务器传入a)用户的IP地址b)CDN Uri请求的IP地址.然后客户端服务器将检查从该特定IP请​​求Uri的次数,并且如果客户端逻辑看到它被请求,请说过去一分钟100次,那么显然这会表示滥用,因为浏览器缓存图像,而恶意请求却没有.因此,客户端计算机只会回复"false"以提供此特定请求的内容.这不是一个完美的解决方案,因为对客户端基础设施的额外回调会导致一个小的延迟,但它肯定比可能卡在一个看起来像你已经存入银行储蓄账户的金额的账单更好.

  2. 更好的解决方案.根据每个ip在特定时间范围内通过CDN提供文件的次数限制.例如,在上面的图像文件的示例中,如果可以将CDN配置为在10分钟的时间范围内服务不超过50个图像请求/ IP /.如果检测到滥用,那么CDN可以在客户定义的时间内a)为特定的滥用uri服务403.或b)如果请求来自滥用者IP,则所有uri的服务器403.所有时间/选项都应保留给客户.这肯定会有所帮助.这里没有回调可以节省时间.缺点是CDN必须跟踪Uri/IP地址/命中数.

哪些解决方案不起作用:

  1. 签名URL不起作用,因为签名查询字符串参数每次都不同,浏览器会不断地对数据进行请求,从而有效地消除了图像的浏览器缓存.

  2. 拥有azure blob的SAS访问签名不会起作用,因为a)每次Uri都不同b)授予SAS后,您可以请求blob的次数没有限制.因此滥用情况仍然存在.

  3. 检查您的日志并简单地禁止IP.我昨天通过匿名代理测试了这种类型的滥用行为,它就像一个魅力.在几秒钟内切换IP并继续滥用(我自己的内容)用于测试目的.所以这也是出来的,除非有一个保姆来监控日志.

可行但但不可行的解决方案:

  1. 过滤Web服务器上的请求.当然,这将是控制问题和跟踪请求/ IP数量的最佳方式,并且在检测到滥用时不会提供内容.但是,您放弃了通过超快速,接近客户端优化的CDN提供内容的巨大好处.此外,通过提供大字节内容(如图像),您的服务器将会大大减慢速度.

  2. 只需咬紧牙关而不用担心.那么......那么你就知道将把你的轮子拿出来的坑洼就在路上,所以不,这个选项不舒服.

综上所述,Azure中带有自定义规则引擎的Premium CDN产品可能会在那里提供一个解决方案,但由于文档非常差并且缺少示例,因此只需要猜测如何正确保护自己,这样就可以了为什么我要写这篇文章.有人曾经解决过这样的问题吗?怎么解决呢?

任何建议都表示赞赏,我对这个问题非常开放.

谢谢你的阅读.

Zap*_*oid -1

这是理论上的,因为我们不为我们的“应用程序”提供服务,但可能很快就会面临这个问题:

难道您不能在您的站点本身上发出一个很快就会过期(10 秒!?)的 cookie 并使用 Azure标准规则引擎进行检查吗?

然后,在您的“主站点”上,您可以进行自定义检查,如果 IP 超出“合理”的请求量,则阻止 IP(或分别不发出 cookie)。一些前提条件:

  • 与通过 CDN 相比,您可能必须对发出 cookie 的“主站点”有更多的控制权。不知道是否可以将这些请求直接“引导”到“客户端服务器”。
  • cookie 必须是 HttpOnly,以免客户端被伪造。

... 我错过了什么?