Веб-приложение ASP.NET предотвращает атаки типа "отказ в обслуживании"

Какие инструменты или методы я могу использовать для защиты своего веб-приложения ASP.NET от атак типа «отказ в обслуживании»


person AJM    schedule 14.06.2011    source источник


Ответы (3)


Попробуйте расширение динамического ограничения IP-адресов http://www.iis.net/download/dynamiciprestrictions.

Не идеальное решение, но помогает поднять планку =)

person Jim    schedule 14.06.2011

Это широкая область, поэтому, если вы можете уточнить свое приложение или уровень угрозы, от которой вы пытаетесь защититься, я уверен, что больше людей смогут вам помочь.

Тем не менее, сразу же вы можете использовать комбинацию кэширующих решений, таких как Squid: http://www.blyon.com/using-squid-proxy-to-fight-ddos/, динамическое ограничение IP-адресов (как объяснил Джим) и, если у вас есть инфраструктура, активный настройка пассивного обхода отказа, когда ваш пассивный компьютер обслуживает замещающий контент, который не затрагивает вашу базу данных / любые другие компьютеры. Это последняя защита, так что вы минимизируете время, на которое DDOS может отключить весь ваш сайт.

person christofr    schedule 14.06.2011

Конечно, аппаратное решение является лучшим вариантом для предотвращения атак DOS, но, учитывая ситуацию, в которой у вас нет доступа к конфигурации оборудования или настройкам IIS, именно поэтому разработчик должен иметь что-то удобное, чтобы заблокировать или, по крайней мере, уменьшить эффект атаки DOS. .

Основная концепция логики основана на коллекции FIFO (First In First Out), такой как Queue, но поскольку она имеет некоторые ограничения, я решил создать свою собственную коллекцию.

Не вдаваясь в подробности, это полный код, который я использую:

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 Attack создают новые сеансы для каждого запроса, в то время как человеческие запросы на веб-сайте содержат несколько запросов, упакованных в один сеанс, поэтому метод может быть вызван в 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);
}

для веб-сайта с тяжелыми запросами вы можете изменить секунды на миллисекунды, но учтите дополнительную нагрузку, вызванную этим кодом.

Я не знаю, есть ли лучшее решение для блокировки преднамеренных атак на веб-сайт, поэтому я ценю любые комментарии и предложения по улучшению кода. К тому времени я считаю это лучшей практикой для предотвращения DOS-атак на веб-сайты ASP.NET программным путем.

person Reza Mortazavi    schedule 19.02.2016