avatar_POCOMAXA

Простой способ защиты от классического HTTP DDoS

Автор POCOMAXA, 2013 Янв. 29, 19:31

« назад - далее »

0 Пользователи и 2 гостей просматривают эту тему.

Ключевые слова [SEO] mu onlineзащитаddos

POCOMAXA

Данное решение позволяет вычислять любых ботов, за исключением тех, которые полностью имитируют работу браузера.

Данное решение позволяет вычислять любых ботов, за исключением тех, которые полностью имитируют работу браузера.

Как это работает

Бот запрашивает страницу, например habrahabr.ru/search/. Бот не умеет загружать вместе со страницей картинки, скрипты, css и пр. Значит в логе будет отображен запрос к /search/ и всё.
Если на habrahabr.ru/search/ заходит живой человек через браузер, то вместе с /search/ в лог попадет множество картинок, скриптов, css и пр.

Настройка

Mysql

/etc/my.cnf
[mysqld]
local-infile=1 #разрешаем load data
# устанавливаем максимальный размер мемори:
max_heap_table_size=1024M
tmp_table_size=1024M

Под рутом:
UPDATE `mysql`.`user` SET `File_priv` = 'Y' WHERE `user`.`Host` = 'localhost' AND `user`.`User` = 'ИМЯ_ЮЗЕРА_БД'; flush privileges;
sysctl

sysctl.conf подробно с комментариями (linux)

Ram drive

Ram drive нужен для ускорения работы с логами nginx-а.
Добавляем в файл /etc/fstab
tmpfs /var/log/ram_disk tmpfs size=1024m 0 0
Затем
mkdir /var/log/ram_disk
mount -t tmpfs -o size=1024m tmpfs /var/log/ram_disk


Алгоритм


1. Выбор ловушки

Берем на сайте любой статичный и ничем не приметный файл (картинка, css, js и пр.), загружаемый при вызове любой страницы динамики, например habrahabr.ru/styles/fontello/css/habr.css
Этот файл нужно сделать некэшируемым, т.е. добавить рандомный параметр, например <?php echo '/styles/fontello/css/habr.css?'.rand(99999999)?>.
Для справки, по умолчанию opera кладет в локальный кэш картинки на 1 час, css/js на 5 минут.

2. Правим конфиг nginx

# делаем нужный нам формат лога
log_format ddos_log '$remote_addrt$msect$status';

# наша ловушка
location =/styles/1347283218/highlight.css {
access_log  /var/log/ram_disk/hook_access.log ddos_log;
}

# вся остальная статика
location ~* ^.+.(class|htc|bmp|cur|jpg|jpeg|gif|png|svg|xls|doc|xhtml|js|css|mp3|ogg|mpe?g|avi|flv|zip|gz|bz2?|rar|ico|txt|jar|swf)$ {
access_log  off;
}

# динамика
location / {
access_log  /var/log/ram_disk/dynamic_access.log ddos_log;
}



3. Создаем таблицы для логов

ENGINE=MEMORY — чтобы было быстрее.
CREATE TABLE `dinamic_log` (
`inc` bigint(20) NOT NULL AUTO_INCREMENT,
`remote_addr` varchar(20) NOT NULL DEFAULT '0',
`time_local` int(20) NOT NULL DEFAULT '0',
`status` int(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`inc`),
KEY `remote_addr` (`remote_addr`),
KEY `time_local` (`time_local`)
) ENGINE=MEMORY AUTO_INCREMENT=1 DEFAULT CHARSET=latin1

CREATE TABLE `hook_log` (
`inc` bigint(20) NOT NULL AUTO_INCREMENT,
`remote_addr` varchar(20) NOT NULL DEFAULT '0',
`time_local` int(20) NOT NULL DEFAULT '0',
`status` int(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`inc`),
KEY `remote_addr` (`remote_addr`),
KEY `time_local` (`time_local`)
) ENGINE=MEMORY AUTO_INCREMENT=1 DEFAULT CHARSET=latin1


Таблица, куда занесем ip поисковых ботов
CREATE TABLE `white` (
`remote_addr` bigint(20) NOT NULL,
PRIMARY KEY (`remote_addr`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

Таблица заблокированных
CREATE TABLE `black` (
`remote_addr` bigint(20) NOT NULL,
`time_local` int(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`remote_addr`),
KEY `time_local` (`time_local`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1


4. Главный скрипт

Для простоты понимания написано на php, т.к. этот язык знают почти все. И обработка ошибок убрана также — для простоты понимания.

// файл лога динамики
$dinamic_log = $argv[1];
// файл лога ловушки
$hook_log = $argv[2];
// кол-во запросов к динамике без картинок, после которого будем банить.
$r_stop = $argv[3];
// период за который делаем анализ (храним данные в таблице)
$load_time = $argv[4];
// через сколько сек делаем загрузку лога и анализ
$wait_sec = $argv[5];

function load_log($log, $table) {
$tmp = '/var/log/ram_disk/tmp_ddos_file';
// копируем лог во временный файл
copy ($log, $tmp);
// чистим лог
file_put_contents($log, "", LOCK_EX);
// загружам лог в БД
mysql_query('LOAD DATA CONCURRENT INFILE "'.$tmp.'" IGNORE INTO TABLE '.$table.' FIELDS TERMINATED BY 't' (`remote_addr`, `time_local`, `status`) SET `remote_addr` = INET_ATON(`remote_addr`)');
// удалем временный файл
unlink($tmp);
}

// выполняем в бесконечном цикле
while (true) {
// загружаем лог динамики
load_log($dinamic_log, 'dinamic_log');

// загружаем лог ловушки
load_log($hook_log, 'hook_log');

// ищем ботов. nginx не дает проверять $status, поэтому 200 и 304 фильтруем здесь.
$res = mysql_query('SELECT dinamic_log.remote_addr FROM `dinamic_log` WHERE (`status` = 200 OR `status` = 304) AND`remote_addr` NOT IN (SELECT `remote_addr` FROM `hook_log`) AND`remote_addr` NOT IN (SELECT `remote_addr` FROM `white`) GROUP BY `remote_addr` HAVING count(inc)>'.$r_stop);
while ($row = mysql_fetch_array($res))
{
// логируем забаненые ip
mysql_query('INSERT INTO black(`remote_addr`) VALUES ('.$row['remote_addr'].')');
// блокируем ip
switch (PHP_OS) {
case "FreeBSD":
system('/sbin/route add -host '.$row['remote_addr'].' 127.0.0.1 -blackhole');
break;
case "Linux":
system('/sbin/ip route add blackhole '.long2ip($row['remote_addr']));
break;
}
}
// чистим таблицу от старых логов
mysql_query('DELETE FROM `log` WHERE `time_local` < (UNIX_TIMESTAMP() - '.$load_time.')');
// ждем
sleep($wait_sec);
}

Запускаем:
php ddoshook.php /var/log/ram_disk/dynamic_access.log /var/log/ram_disk/hook_access.log 5 300 3

5. Разбаниваем

$block_time = $argv[1]; // на какое время баним ip.
$res = mysql_query('SELECT `remote_addr` FROM black WHERE time_local < (UNIX_TIMESTAMP() - '.$block_time.')');
while ($row = mysql_fetch_array($res)) {
// разблокировка ip
switch (PHP_OS) {
case "FreeBSD":
system('/sbin/route delete '.$row['remote_addr']);
break;
case "Linux":
system('/sbin/ip route delete '.long2ip($row['remote_addr']));
break;
}
}

Помещаем в крон
* * * * * /usr/bin/php unban.php 86400

Вот и всё, боты банятся, люди пропускаются.

В следующих выпусках:
Как выдерживать syn/udp/icmp flood на пределах возможностей сервера и канала.
Как безошибочно определять поисковых ботов, не обращая внимания на юзер-агенты.
7 методов, которые помогли отбить более 1000 http ddos-атак.
Как получить профессиональную защиту от ddos-атак, заплатив всего 5$.


upd
Как узнать IP поисковых ботов?

Ищем AS нужного поисковика, например здесь: bgp.potaroo.net/cidr/autnums.html
Получаем IP адреса для AS: stat.ripe.net/data/announced-prefixes/data.json?resource=AS15169

Cписки AS и IP нужно постоянно обновлять.

upd 2

OS: FreeBSD 8.3
CPU: E5-2620 2.00GHz

Тест 1

rows(dinamic_log): 100000 (100 000 http-запросов к динамике сайта за 3 секунды)
rows(hook_log): 1000 (1000 легитимных запросов от пользователей за 3 секунды)

# php /root/scripts/php/imgtest/ddos_hook.php /tmp/d20.log /tmp/h20.log 5 300 3
LOAD DATA time elapsed: 0.29 sec.
LOAD DATA time elapsed: 0.003 sec.
select time elapsed: 0.017 sec.
rows(ban): 1800
full cicle time elapsed: 0.313 sec.

Тест 2

rows(dinamic_log): 1000000 (1 млн. http-запросов к динамике сайта за 3 секунды)
rows(hook_log): 10000 (10 000 легитимных запросов от пользователей за 3 секунды)

# php /root/scripts/php/imgtest/ddos_hook.php /tmp/d2.log /tmp/h2.log 5 300 3
LOAD DATA time elapsed: 2.878 sec.
LOAD DATA time elapsed: 0.023 sec.
select time elapsed: 0.501 sec.
rows(ban): 12402
full cicle time elapsed: 3.54 sec.

P.S.
Описанное в статье решение является экспериментальным. Используйте на свой страх и риск

По материалам https://habrahabr.ru/

Ссылка на непосредственно оригинальную статью ТУТ

epmak

#1
Спойлер
россомаха, будь добр, расскажи мне, пожалуйста, как  защититься от ДДОСА, который валит мне сервис, с помощью mysql?  способ с ботами забавный. но не надо путать обычных ботов и ботов досилки :D  мне на шапре ничего не стоит написать бота, который имитирует пользователя, т.е. "выкачивает" картинки, стили... но с 1 страницы,на которую он и будет дуплиться, с разными гет параметрами например...(да, это для 1 сайта, но если этой штукой флудить с 3-5 компов, через прокси разные.. ы.. это имитация ботнета, причем ровно во столько потоков, сколько потянет комп. а в моем распоряжении, чисто гипотетически, допустим, есть сервер на базе ксеона с 18 логическими ядрами и туча оперативы, так же канал 100мб/с  это выйдет аля пару к ботов с разными ипами, и серваку будет ацкий нежданчик) и чем это кончится? ты бы просто статьи из инета не выкачивал...

И СКОЛЬКО РАЗ ТВЕРДИЛИ МИРУ НЕ СПАСТИСЬ ОТ ДДОСА ХТТП СРЕДСТВАМИ САМОГО СЕРВИСА! да, есть модули на апачу и на нгинкс, которые способны несколько облегчить жизнь сервису под досом, но блин, дос !=ддос и защищаться от него с помощью пхп скриптов, все равно что против армии выйти 1 человеком - сметут и не заметят. Давно уже на уровне аппаратов делают защиту. анализ трафика, анализ запросов на сервер, анализ поведения бот/человек, там целая наука, как  и что. Даже досилок сейачс разных куча, которые способны обойти этот алгоритм...

за старания 5/5, за подбор материала 2/5.

П.С. я не хейтер. объективно смотрю на проблему, ибо имеет место быть.
[свернуть]

POCOMAXA

Леша, без личного, в данной ситуации ты выступил как Хейтер, внизу, в данной статье, есть коменты, почитай их, посмотри, что люди пишут, попробуй реализовать то что написано. А вот только тогда критикуй, я не спорю, что ты сильный веб кодер, но не стоит утверждать что
ЦитироватьИ СКОЛЬКО РАЗ ТВЕРДИЛИ МИРУ НЕ СПАСТИСЬ ОТ ДДОСА ХТТП СРЕДСТВАМИ САМОГО СЕРВИСА
, от мощного ддоса, ложится даже Пентагон и это факт. Здесь речь идет о таких ддосах, аля бот БлекЕнерджи (паблик) которые, как раз и актуальны для данного форума.

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

Killbrum

умник и любитель настраивать фаерволлы. А не судьба было моментарии запостить? Ладно. Для сверх умных. Ответ самого автора статьи о эффективности
Спойлер
DDoSExpert,13 сентября 2012 в 21:41#↵↑
Данное решение было придумано нами несколько дней назад, тест был всего на 2-х атаках, сайты не крупные.
[свернуть]

бесят придурки вроде РОСОМАХИ и 000000 которые тупо копипастят и даже не думают что они копипастят

а еще для особых умников

Спойлер
nayjest,13 сентября 2012 в 18:36# + 32
+ еще один уровень защиты: поисковые боты тоже идут лесом, так что те, кто мог бы заDDoSить ваш сайт, его даже не найдут :)
[свернуть]

epmak

Цитата: POCOMAXA от 2013 Янв. 30, 11:38  Леша, без личного, в данной ситуации ты выступил как Хейтер
если я попрошу аргументировать, сможешь адекватно ответить, без надписей "вон, на хабре писали". Там много чего пишут, и много троллят и что, всему верить?


что ты сильный веб кодер
чепуха!

Цитировать[...]БлекЕнерджи (паблик) которые, как раз и актуальны для данного форума.
не совсем согласен. Помнишь ситуацию с sync flooder'om он IA или кто там его писал - не помню.(Он и по сей день иногда бывает очень полезен). Но я к тому, что убьешь ты 1 вид спрута, на его место встанет второй более мощный(аналогия с синкфлудером - трюки с пакетами на определенный порт) с триалом а ля "100 потоков нахаляву", а, поверь, если напрячь пару знакомых, самому и еще чутка народу поднайти, и даже 100 коннектов эти будут страшны с 1 компа. Дос - это не обязательно долбежка в 1 точку. Досить надо тоже уметь.

Дети, кстати, может сами и не будет досить, наймут на пару дней "гастарбайтеров", вроде и ничего страшного, а рейтинг тебе подпортят и нервишки тоже.

1.
Данное решение позволяет вычислять любых ботов, за исключением тех, которые полностью имитируют работу браузера.
самое первое что бросилось в глаза. перевожу на язык программиста:
прежде чем начинать атаку на любой ресурс его "щупают", ищут "тонкие места", то есть места, которые вызывают нагрузку и места, в которые проще всего долбить флудом по хттп.
ты предлагаешь проверять, как себя ведет законнекченный пользователь - качает ли изображения, обращается ли к файлам стилей и проч. Что мне мешает найти мне нужную страницу, внести в код бота, чтобы он делал запрос и туда тоже? мне не обязательно скачивать ВЕСЬ контент, мне достаточно обратиться только к нужным файлам. Алгоритм относительно линеен, можно вычислить. Далее, берем пул потоков ну и...
Что хорошего:
- тратится время на обращение к "левым" картинкам, небольшой парсинг страницы на наличие подстав "rand()"
- есть "черный лист" ипов

Что плохого
- если ваш сайт на Mssql, то нужно переделать либо скрипт, либо дополнительно ставить базу мускула
- множественные почти одинаковые обращения к бд пусть и не сильно нагружают сервер, но требуют ресурсов
- скрипт ПХП, как ты думаешь как себя поведет от 1000 одновременных или почти одновременных/асинхронных  запросов, создавая темповый файл?
- большая вероятность, что в  "Черном листе" будут еще и поисковые боты, пусть не самые крупные, но будут.

2.
Цитировать+ еще один уровень защиты: поисковые боты тоже идут лесом, так что те, кто мог бы заDDoSить ваш сайт, его даже не найдут :)
Цитировать>Бот не умеет загружать вместе со страницей картинки, скрипты, css и пр.
Научить бота это делать — дело 10-ти строк кода
ЦитироватьВыскажу свое мнение. Я бы побоялся пользоваться вашими услугами после такой статьи, позвольте объяснить почему:
1) Использование MySQL(!), которая часто и так является бутылочным горлышком производительности веб приложений.
1b) LOAD DATA для логов, парсинг этого дела... да еще и при DDoS (при парсинге по интервалам, лог будет больше обычного)? Какой перерасход ресурсов, не находите?
2) Абсолютная неподготовленность к ботам, которые работают на браузерных движках.
2b) Если такие боты слишком круты для этой статьи, то мне ничего не мешает написать скрипт который будет дергать все данные на странице, получать 5 байт и отваливаться, в лог запишется, защита пройдена.
3) Плохой сценарий работы с реальными клиентами, не учтены кеширующие прокси, кеши браузера (всех браузеров), итд.
4) К сожалению, в случае использования мултифронтендов логи придется собирать по ним, что также не учтено.

Что я бы предпочел вместо всего этого огорода, да и работающее на фронтенд серверах, без баз данных и прочего — это простые счетчики запросов, и несколько основных критериев подозрения:
1) Слишком много запросов (Abnormal)
2) уникальные счетчики запросов для каждого IP со списками лимитов на действия за период времени, таким образом в случае повторного поиска, пользователя случайно не забанят.
3) чтобы счетчики работали лучше и не были подвержены атаке на несуществующие URL — брать только элементы URL через компилированный regex для скорости.
сопсно, о чем и речь
постов там много, на самом деле. много оч интересных постов, почитав их омжно не хилую досилку запилить, кстати :)

Я просто с тобой веду разговор как человек, который представляет, как работает хттп протокол (пришлось учить на одной из сессий - писали свой хттп сервер) и я представляю КАК вообще там идет "движуха" и как действует бот. На "про" я не претендую, но тема интересная и злободневная, приходится вертеться. И как раз - таки учитывая нашу комьюнити - прохост для них самое лучшее решение.
вообще, аппаратный уровень защиты гораздо быстрее, лучше и стабильнее, хоть и дороже, имхо.

П.С. я не веду себя как хейтер. оно мне бессмысленно.

POCOMAXA

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

Опять таки, это попытка сделать хоть какие то шаги, а не флудить в теме про то кого и как заддосили.

epmak

так в том и парадокс, что понимающий лезет в суть, чтобы понять КАК решать, потом уже сопоставляет варианты и свои возможности. Заметь, что все админы более-менее крумно-стабильных серверов не забывают о данной проблеме и каждый нашел выход - кто прохост, кто роутеры, кто другие средства. вариантов много, но всегда начинать стоит с изучения предмета, иначе никак. ты и сам, наверно, уже перепрочел все коменты и сделал выводы. И, надеюсь, теперь предельно ясно, что я был объективен.

п.с.
Спойлер
но я не забыл редиско, что ты хотел меня захейтерить (rofl)
Спойлер
шучу. мне реально пофиг
[свернуть]
[свернуть]

Похожие темы (5)