ASP.NET Web应用程序防止拒绝服务攻击

发布于 2024-11-15 16:48:09 字数 49 浏览 2 评论 0原文

我可以使用哪些工具或技术来保护我的 ASP.NET Web 应用程序免受拒绝服务攻击

What tools or techniques can I use to protect my ASP.NET web application from Denial Of Service attacks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你是我的挚爱i 2024-11-22 16:48:09

当然,硬件解决方案是防止 DOS 攻击的最佳选择,但考虑到您无法访问硬件配置或 IIS 设置的情况,这绝对是开发人员必须拥有方便的东西来阻止或至少减少 Dos 攻击效果的原因。

逻辑的核心概念依赖于 FIFO(先进先出)集合,例如队列,但由于它有一些限制,我决定创建自己的集合。

在不讨论更多细节的情况下,这是我使用的完整代码:

public class AntiDosAttack
{
  readonly static List<IpObject> items = new List<IpObject>();

  public static void Monitor(int Capacity, int Seconds2Keep, int AllowedCount)
  {
    string ip = HttpContext.Current.Request.UserHostAddress;

    if (ip == "")
    return;

    // This part to exclude some useful requesters
    if(HttpContext.Current.Request.UserAgent != null && HttpContext.Current.Request.UserAgent == "Some good bots")
      return;

    // to remove old requests from collection
    int index = -1;
    for (int i = 0; i < items.Count; i++)
    {

      if ((DateTime.Now - items[i].Date).TotalSeconds > Seconds2Keep)
      {
        index = i;
        break;
      }
    }

    if (index > -1)
    {
      items.RemoveRange(index, items.Count - index);
    }

    // Add new IP
    items.Insert(0, new IpObject(ip));

    // Trim collection capacity to original size, I could not find a better reliable way
    if (items.Count > Capacity)
    {
      items.RemoveAt(items.Count - 1);
    }

    // Count of currect IP in collection
    int count = items.Count(t => t.IP == ip);

    // Decide on block or bypass
    if (count > AllowedCount)
    {
      // alert webmaster by email (optional)
      ErrorReport.Report.ToWebmaster(new Exception("Blocked probable ongoing ddos attack"), "EvrinHost 24 / 7 Support - DDOS Block", "");

      // create a response code 429 or whatever needed and end response
      HttpContext.Current.Response.StatusCode = 429;
      HttpContext.Current.Response.StatusDescription = "Too Many Requests, Slow down Cowboy!";
      HttpContext.Current.Response.Write("Too Many Requests");
      HttpContext.Current.Response.Flush(); // Sends all currently buffered output to the client.
      HttpContext.Current.Response.SuppressContent = true;  // Gets or sets a value indicating whether to send HTTP content to the client.
      HttpContext.Current.ApplicationInstance.CompleteRequest(); // Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event.
    }
  }

  internal class IpObject
  {
    public IpObject(string ip)
    {
      IP = ip;
      Date = DateTime.Now;
    }

    public string IP { get; set; }
    public DateTime Date { get; set; }
  }
}

内部类旨在保留请求的日期。

当然,DOS 攻击请求会在每个请求上创建新的会话,而网站上的人工请求包含打包在一个会话中的多个请求,因此可以在 Session_Start 中调用该方法。

用法:

protected void Session_Start(object sender, EventArgs e)
{
   // numbers can be tuned for different purposes, this one is for a website with low requests
   // this means: prevent a request if exceeds 10 out of total 30 in 2 seconds
   AntiDosAttack.Monitor(30, 2, 10);
}

对于请求繁重的网站,您可以将秒更改为毫秒,但请考虑此代码造成的额外负载。

我不知道是否有更好的解决方案来阻止对网站的故意攻击,因此我感谢任何改进代码的评论和建议。到那时,我认为这是以编程方式防止对 ASP.NET 网站进行 DOS 攻击的最佳实践。

For sure a hardware solution is the best option to prevent DOS attacks, but considering a situation in which you have no access to hardware config or IIS settings, this is definitely why a developer must have something handy to block or at least decrease dos attack effect.

The core concept of logic relies on a FIFO (First In First Out) collection such as Queue, but as it has some limitations I decided to create my own collection.

Without discussing more details this is the complete code I use:

public class AntiDosAttack
{
  readonly static List<IpObject> items = new List<IpObject>();

  public static void Monitor(int Capacity, int Seconds2Keep, int AllowedCount)
  {
    string ip = HttpContext.Current.Request.UserHostAddress;

    if (ip == "")
    return;

    // This part to exclude some useful requesters
    if(HttpContext.Current.Request.UserAgent != null && HttpContext.Current.Request.UserAgent == "Some good bots")
      return;

    // to remove old requests from collection
    int index = -1;
    for (int i = 0; i < items.Count; i++)
    {

      if ((DateTime.Now - items[i].Date).TotalSeconds > Seconds2Keep)
      {
        index = i;
        break;
      }
    }

    if (index > -1)
    {
      items.RemoveRange(index, items.Count - index);
    }

    // Add new IP
    items.Insert(0, new IpObject(ip));

    // Trim collection capacity to original size, I could not find a better reliable way
    if (items.Count > Capacity)
    {
      items.RemoveAt(items.Count - 1);
    }

    // Count of currect IP in collection
    int count = items.Count(t => t.IP == ip);

    // Decide on block or bypass
    if (count > AllowedCount)
    {
      // alert webmaster by email (optional)
      ErrorReport.Report.ToWebmaster(new Exception("Blocked probable ongoing ddos attack"), "EvrinHost 24 / 7 Support - DDOS Block", "");

      // create a response code 429 or whatever needed and end response
      HttpContext.Current.Response.StatusCode = 429;
      HttpContext.Current.Response.StatusDescription = "Too Many Requests, Slow down Cowboy!";
      HttpContext.Current.Response.Write("Too Many Requests");
      HttpContext.Current.Response.Flush(); // Sends all currently buffered output to the client.
      HttpContext.Current.Response.SuppressContent = true;  // Gets or sets a value indicating whether to send HTTP content to the client.
      HttpContext.Current.ApplicationInstance.CompleteRequest(); // Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event.
    }
  }

  internal class IpObject
  {
    public IpObject(string ip)
    {
      IP = ip;
      Date = DateTime.Now;
    }

    public string IP { get; set; }
    public DateTime Date { get; set; }
  }
}

The internal class is designed to keep the date of request.

Naturally DOS Attack requests create new sessions on each request while human requests on a website contain multiple requests packed in one session, so the method can be called in Session_Start.

usage:

protected void Session_Start(object sender, EventArgs e)
{
   // numbers can be tuned for different purposes, this one is for a website with low requests
   // this means: prevent a request if exceeds 10 out of total 30 in 2 seconds
   AntiDosAttack.Monitor(30, 2, 10);
}

for a heavy request website you may change seconds to milliseconds but consider the extra load caused by this code.

I am not aware if there is a better solution to block intentional attacks on website, so I appreciate any comment and suggestion to improve the code. By then I consider this as a best practice to prevent DOS attacks on ASP.NET websites programmatically.

淡忘如思 2024-11-22 16:48:09

尝试动态 IP 限制扩展 http://www.iis.net/download/dynamiciprestrictions

完美的解决方案,但有助于提高标准 =)

Try the Dynamic IP Restriction extension http://www.iis.net/download/dynamiciprestrictions

Not a perfect solution, but helps raise the bar =)

孤寂小茶 2024-11-22 16:48:09

这是一个广泛的领域,因此如果您可以更具体地说明您的应用程序或您要防范的威胁级别,我相信更多的人可以为您提供帮助。

但是,您可以立即选择缓存解决方案的组合,例如 Squid: http://www.blyon.com/using-squid-proxy-to-fight-ddos/,动态 IP 限制(如 Jim 所解释),如果您有基础设施,主动-被动故障转移设置,其中您的被动计算机提供占位符内容,该内容不会访问您的数据库/任何其他计算机。这是最后一道防线,可以最大限度地减少 DDOS 导致整个站点脱机的时间。

It's a broad area, so if you can be more specific about your application, or the level of threat you're trying to protect against, I'm sure more people can help you.

However, off the bat, you can go for a combination of a caching solution such as Squid: http://www.blyon.com/using-squid-proxy-to-fight-ddos/, Dynamic IP Restriction (as explained by Jim) and if you have the infrastructure, an active-passive failover setup, where your passive machine serves placeholder content which doesnt hit your database / any other machines. This is last-defence, so that you minimise the time a DDOS might bring your entire site offline for.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文