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

StackOverflow https://stackoverflow.com/questions/6340843

Вопрос

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

Это было полезно?

Решение

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

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

Другие советы

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

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

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

Основная концепция логики основана на коллекции FIFO (первым пришел — первым обслужен), такой как 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top