| Главная | Журнал | Форум | Wiki | DRKB | Страны мира |
Защита от DOS-атак в ASP.NETВеб-сервисы являются самой привлекательной мишенью для хакеров. Даже школьник может большим количеством запросов уронить сайт на котором выполняются скрипты, создающие ощутимую нагрузку на серверную операционную систему. Особенно хорошо в качестве мишени подходят страницы, на которых расположено большое количество информеров, обрабатываемых серверными скриптами (такими как Ajax). Чтобы самостоятельно устроить такую атаку, достаточно запустить элементарный код: for( int i = 0; i < 100000; i ++ )
{
WebClient client = new WebClient();
client.DownloadString("http://www.microsoft.com/default.aspx");
}
Уже после нескольких запросов Вы обнаружите, что в ответ от сервера приходит страница с ошибкой. Однако, это совсем не значит, что сервер уже упал. Просто сайт отверг Ваши последние запросы. Таким образом Вы получили отказ в ообслуживании (Denial of Service или сокращённо DOS). Самым простым способом защиты от подобного флуда является подсчёт количества запросов с определённого айпишника и запоминание этого значения в кэше ASP.NET. А когда количество запросов превысит допустимый порог, то отвергать запросы с этого адреса в течение определённого срока, например на 10 минут. Через 10 минут вновь начать обрабатывать поступающие запросы с конкретного айпишника. Ниже приведён пример класса ActionValidator, который позволяет запоминать такие параметры посетителя как первый визит, последующий визит, асинхронные постбэки, добавление нового виджета, создание новой страницы и т.д. В классе по каждому параметру заданы предельно допустимые значения для конкретного IP-адреса. public static class ActionValidator
{
private const int DURATION = 10; // 10-минутный период
public enum ActionTypeEnum
{
FirstVisit = 100, // Самый значимый параметр, подбирать его значение надо осторожно.
ReVisit = 1000, // Повторные посещения особо не ограничиваем
Postback = 5000, // Это тем более не проблема
AddNewWidget = 100,
AddNewPage = 100,
}
Далее рассмотрим статический метод IsValid, который проверяет не достигнуто ли предельное значение по каждому типу запраса. Метод возвращает true, если лимит по запросу не достигнут и false, если запрос пользователя можно отклонить. Если IsValid вернул false, то можно просто вызвать Request.End(), тем самым защитив ASP.NET от дальнейшей загрузки. Так же можно сделать редирект на страницу с сообщением о превышении количества запросов с этого айпи. public static bool IsValid( ActionTypeEnum actionType )
{
HttpContext context = HttpContext.Current;
if( context.Request.Browser.Crawler ) return false;
string key = actionType.ToString() + context.Request.UserHostAddress;
var hit = (HitInfo)(context.Cache[key] ?? new HitInfo());
if( hit.Hits > (int)actionType ) return false;
else hit.Hits ++;
if( hit.Hits == 1 )
context.Cache.Add(key, hit, null, DateTime.Now.AddMinutes(DURATION),
System.Web.Caching.Cache.NoSlidingExpiration,
System.Web.Caching.CacheItemPriority.Normal, null);
return true;
}
Ключом в кэше является пара: "типа действия" и IP-адрес клиента. Сначала идёт проверка, есть ли в кэше точно такая же пара. Если нет, то пара добавляется в кэш и начинается отсчёт срока. По истечение срока пара автоматически удалится из кэша и, если пользователь продолжит посещение сайта, то всё повторится сначала. В случае если пара уже присутствует в кэше, то метод проверяет не достигнут ли предел и, если нет превышения, то счётчик увеличивается на еденицу. Принудительно записывать новое значение счётчика в кэш не нужно, так как hit всего лишь ссылается на строку в кэше и обновление счётчика происходит автоматически. Однако если это сделать, то значение экспирации в кэше для данной пары будет обновлено и нарушится логика возобновления отсчёта на конкретный срок. Использовать этот класс можно прямо на default.aspx: protected override void OnInit(EventArgs e)
{
base.OnInit(e);
// Проверяем можно ли обработать повторное посещение
if( !base.IsPostBack )
{
// Блокируем запросы без кукисов
if( Profile.IsFirstVisit )
{
if( !ActionValidator.IsValid(ActionValidator.ActionTypeEnum.FirstVisit))
Response.End();
}
else
{
if( !ActionValidator.IsValid(ActionValidator.ActionTypeEnum.ReVisit) )
Response.End();
}
}
else
{
// Ограничение количества постбэков
if( !ActionValidator.IsValid(ActionValidator.ActionTypeEnum.Postback) )
Response.End();
}
}
В этом примере проверяются первый визит, повторный визит, постбэки и т.д. Конечно, защиту от DoS атак можно переложить на плечи брэндмауэров, таких как Cisco. Любой хостинг-провайдер будет уверять Вас, что вся их сеть защищена от DOS и DDOS (Distributed DOS) атак. Однако, от TCP SYN атак и флуда кривых пакетов они защищаются на аппаратном уровне, в то время как DOS-атаки работают на уровне приложения и, соответственно, защита от них так же должна быть встроена в приложение. Не многие сайты применяют подобные меры защиты своих приложений, поэтому если У Вас есть широкополосный канал в интернет из дома и Вам, по каким-то причинам станет скучно, то можете попробовать поиздеваться над каким-нибудь сайтом :) |
Основные разделы сайта
|
|
|