Простая программная защита от DDoS-атаки
Блог 24 сентября 2014
DDoS (сокр. от англ. Distributed Denial
of Service, Распределённый отказ от обслуживания) — изначально тип сетевой атаки,
основанной на небезграничности ресурсов атакуемой службы, к которой
организуется масса запросов, с которыми она заведомо
не сможет справиться, и будет вынуждена отказать в обслуживании (либо заставить ждать неприемлемо долго),
собственно, отсюда и название.
DDoS может быть организована по заказу конкурентов или "в учебных целях" начинающим хакером. Заносить вручную в "черный
список" атакующие ip-адреса обычно неэффективно,
так как они передают "эстафетную палочку". Атака может длиться несколько суток и вестись тысячами
компьютеров, превращенных в "зомби".
Многие компании предлагают аппаратные методы защиты за немаленькие деньги. Однако имеется простое (но не всегда
эффективное) программное решение,
позволяющее снять остроту проблему. Суть - игнорировать "назойливые" запросы. Ниже пример на C#.
Код программы.
<%@ Page Language="C#"%>
<script runat="server">
//класс
для статистики по Ip-адресам
public class Xvisit
{
public long cnt = 1; //количество вызовов
public long dt = 0; //время
последнего незаблокированного вызова
}
//объект для безопасной многопоточной работы
static private readonly Object theLock = new Object();
//словарь - в качестве ключа Ip-адреса
static protected Dictionary<string, Xvisit> dict = new Dictionary<string, Xvisit>();
void
AnalyzeIp()
{
bool bReject = false;
string ipa = Request.UserHostAddress;
lock (theLock)
{
if
(dict.Count == 0 || dict.Count > 10000)
{ //проинициировать словарь
if (dict.Count > 10000)
{ //добавить
больше функциональности
//...
dict.Clear();
}
Xvisit x = new
Xvisit();
x.dt = DateTime.Now.Ticks; //запомнить время инициации
dict.Add("me", x);
}
else
{
Xvisit vis = null;
if (dict.TryGetValue(ipa, out vis))
{ //адрес уже встречался
long dt = DateTime.Now.Ticks;
TimeSpan ts = TimeSpan.FromTicks(dt - vis.dt);
double msec =
ts.TotalMilliseconds;
if (msec < 3000)
{ //зачастили!
bReject = true;
}
else vis.dt = dt;
vis.cnt++;
}
else
{ //добавить новый
адрес в словарь
Xvisit x = new Xvisit();
x.dt = DateTime.Now.Ticks;
dict.Add(ipa, x);
}
}
}
if( bReject )
{ //сервер перегружен
Response.Write("Server is busy." + ipa);
Response.End();
}
}
protected void Page_PreInit(object sender, EventArgs e)
{
AnalyzeIp();
}
protected void Page_Load(object sender, EventArgs e)
{
//код
}
</script>
Пояснения к коду
программы.
Определяем ip-адрес, откуда идет запрос. Если запрос повторился в течении короткого времени, игнорируем его. Для этого создаем словарь входящих
запросов и ведем статистику.
if (dict.Count > 10000)
{ //добавить больше функциональности
//...
}
вместо
количества наколенных адресов можно использовать и время прошедшее после инициализации словаря (используем ключ "me").
Затем можно определить адреса,
участвующие в атаке и послать письмо администратору сайта. Можно автоматически добавить эти адреса в черный список.
Например, для iis выполнить в консоли
команду типа appcmd set config /section:ipsecurity /+"[ipaddress='10.0.0.1',allowed='false']"
Комментарии
Добавить комментарий могут только авторизованные пользователи.
Авторизоваться