HTTP-флуд — это массированная атака на веб-сервер, которая сопровождается посылкой огромного кол-ва http-запросов.
Три ступени борьбы с HTTP-флудом
- Активируем IPFW
- Пишем наш файерволл
- Пишем парсер логов и добавляем их в черный список
Активируем IPFW
Добавим в /etc/rc.conf
firewall_script="/etc/fw.sh"
firewall_logging="YES"
Внимание! Не перезагружайтесь сразу же, так как получите бан по сети и не сможете влезть в ssh. Тем у кого есть физический доступ — это не касается естественно! :)
Пишем наш файерволл
Создаем наш файерволл в файл /etc/fw.sh
FwCMD="/sbin/ipfw"
${FwCMD} -f flush
${FwCMD} 10 add check-state
${FwCMD} 40 add allow all from "table(1)" to me
cat /etc/fw_white_list | awk '{ if ($1!="") {system("ipfw table 1 add "$1"")} }' > /dev/null
${FwCMD} 50 add deny all from "table(2)" to me
cat /etc/fw_black_list | awk '{ if ($1!="") {system("ipfw table 2 add "$1"")} }' > /dev/null
${FwCMD} 100 add allow ip from any to any
с правами файлов надеюсь сами разберетесь...
В table (1) будет содержаться список IP, которые могут заходить в любом случае (для админов :).
В table (2) будет содержаться список IP, которым вы запрещаете заходить к вам.
Теперь потестим наши правила!
Будет что-то типа того:
00050 0 0 deny ip from table(2) to me
Если есть table (1) и table (2), то все в порядке, если нет, то попробуйте создать их вручную:
# ipfw 50 add deny all from "table(2)" to me
Тестим содержимое наших table
# ipfw table 2 list
Должны быть списки вида:
222.222.222.222/32 0
Если ipfw не запускается, то используйте полный путь /sbin/ipfw.
Теперь можно и перезагрузить сервер, для применения настроек.
Пишем парсер логов и добавляем их в черный список
Я использую nginx для фронтенда, поэтому буду анализировать его access-логи, но вы можете сами написать регулярку для парсинга логов apache например...
Для nginx надо создать дополнительный файл access-лога «/var/log/nginx/access-ddos.log», просто мне так удобнее, но вы можете не заморачиваться, а использовать один лог. Мне просто удобно с двумя, один имеет в себе полный лог, а второй я порой подчищаю.
Создадим файл /etc/banip.sh, который будет собирать IP и добавлять их в бан!
# зачищаем fw_black_list
echo '' > /etc/fw_black_list
# выберем с помощью регулярок IP, у которых нет Useg-Agent'а, отсортируем с уникальным ключом
cat /var/log/nginx/access-ddos.log | awk ' match($0, /(\d*.\d*.\d*.\d*).*"-" "-"/) {print $1}' | sort | uniq >> /etc/fw_black_list
# чистим лог
# echo '' > /var/log/nginx/access-ddos.log
# сбрасываем таблицу с забаненными IP
/sbin/ipfw table 2 flush
# добавляем в таблицу список забанненых IP
cat /etc/fw_black_list | awk '{ if ($1!="") {system("/sbin/ipfw table 2 add "$1"")} }' > /dev/null
Вот пример лога с http-флудом + нормальные запросы от пользователей (162.115.149.232)
162.115.149.232 - - [31/Mar/2009:14:01:00 +0000] "GET / HTTP/1.1" 200 8960 "http://example.com./" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322)"
111.111.111.111 - - [31/Mar/2009:14:02:00 +0000] "GET / HTTP/1.1" 304 0 "-" "-"
222.222.222.222 - - [31/Mar/2009:14:03:00 +0000] "GET / HTTP/1.1" 304 0 "-" "-"
С помощью регулярки
можно и без регулярки см. каммент
получим
111.111.111.111
222.222.222.222
после чего переведем поток и отсортируем уникальные IP в списке
и получим в результате:
222.222.222.222
вот этот результат и пойдет в черный список!
Добавить в cron задание
Ставим в cron задание, пусть сам проверяет теперь и добавляет IP в бан.
С установкой времени думаю сами разберитесь, потому что зависит от конкретной ситуации.
P.S. Написал этот пост как можно проще, для того чтобы каждый мог легко разобраться с этой напастью и решить проблему. Рекомендую изучить или хотябы ознакомится с прежде чем что-то менять, так же без здесь никуда...
UPD: Забыл сказать, думаю назревает вопрос зачем нам «/etc/fw.sh»? Это для того чтобы перезагружать файерволл и изменять правила.


Прекольно
Прикольно? А что ава тогда грусная? :)
[...] ipfw ddos Оставить комментарий | Comment RSS | Теги: SEO, Сервисы Назад: Hello, World! Далее: Начинающим блоггерам! Выбор блога, регистрация в каталогах, поисковиках и закладках. [...]
/d*.d*.d*.d*.*"-" «-»/
шо за кривая регулярка?
Вот так я и узнал, что у меня на серваке с надписью FreeBSD 7 на самом деле крутится FreeBSD 5.2.1, в которой ipfw ещё команду table не знает %)
Mabp, отличная регулярка, что работает то лучше не менять :P
Zhilinsky, будешь обновлять систему?
врешь ты все ©
у тебя под нее вот такая строка пройдет как дети в школу
0000 text «-» «-»
И пройдет туда «0000», в чем проблема то? У меня IP пишет nginx, считаешь он может туда добавить «0000»?
Заключил выборку в круглые скобки, может ты поэтому паришься?
бля, напиши как человек
/\d+\.\d+\.\d+\.\d+.*"-" «-»/
Мавр, так регулярка не будет работать, проверено. Почитай про AWK...
Неа, мне лень... Да и работает. Может ipfw обновлю.
Zhilinsky, ты просто список IP через запятую добавляешь чтоли?
Сейчас сделано несколько разрешающих и запрещающих правил на подсети, а я хотел прикрутить по такой схеме блокировку IP-адресов, с которых основной поток спама идёт, чтобы exim не обрабатывал этот мусор и не грузил машину.
херня какаято
Zhilinsky, можешь просто так же парсить, потом склеивать в одну строку через запятую и добавлять в правило... Есть конечно и ограничение, но не помню сколько именно...
CTAPbIu_MABP, попробуй потестить сам, если не веришь...
верю, читал, просто странно что там не pcre
Что-то мне подсказывает, что это обходится, но сформулировать алгоритм обхода я не могу :)
IP-адрес хранится в пакете, приходящем снаружи, а не определяется на месте. Следственно, его можно хитро подделать :-)
По крайней мере, меня так учили =)
dallone, от любого ддоса нельзя защитится на 100%, даже с железками.
А в моем алгоритме учитываются юзеры без User-Agent, если боты начнут засылать UA, то я поменяю алгоритм :)
Mabp, ты был прав, что-то странно в регулярке, парсер вордпресса съел бекслеши пере «d»
я ж говорил.
но перед точкой по идеи тоже надо она же за любой символ идет
>я ж говорил.
я знаю что парсер бесится из-за плагина keywords... только пока не знаю что поправить.
>но перед точкой по идеи тоже надо она же за любой символ идет
думаю так как нет за точкой литерала указывающего кол-во, то она и не срабатывает как маска.
но когда использую \.\d*
то не работает...
литералы количество не указывают, его указывают квантификаторы (от слова quantity — количество)
угу, все время забываю это слово...
хммм... странно...
Почему рег. /(\d*.\d*.\d*.\d*).*"-" «-»/ ?
А разве проблема сделать запрос 162.115.149.232 — — [31/Mar/2009:14:01:00 +0000] «GET / HTTP/1.1» 200 8960 «http://example.com./» «Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322)» ?
Что то не пому как он отличает ддос бота от человека = )))))
Макака, читайте внимательнее пост, я рассказывал про свою проблему и в следствии анлиза выяснилось что боты не передавали UA. И камменты.
да ты дарагой см не знаешь авк. и видимо не понимаешь как он работает))
В результате обсуждений с дудом в скайпе — awk, пришол к выводу что я awk знаю плохо...
решит мою проблему без регулярки
кросавчеги :)
[...] новомодной технологии пыхо-специалистов сегодня удалось раз и навсегда посадить на осиновый [...]
Вы еще не поняли, насколько это охуенная статья!
прогнал парсер через свой лог и не получил на выходе ничего, хотя посещалка на ресурсе порядка 200к уников в сутки. Решил телнетом запросить страницу, поскольку он никаких UA передавать не должен. В ответ получил странную картину:
[root@travka /usr/home/alp]# cat /var/log/httpd/xyy***x-access.log| awk ' match ($0, /(\d*.\d*.\d*.\d*).*"-" «-»/) {print $1}' | sort | uniq
Тут пустота. И тут же делаю выборку своего телнетного запроса:
[root@travka /usr/home/alp]# grep 188.*.*.99 /var/log/httpd/xyyandex-access.log
188.*.*.99 — — [13/Jul/2009:17:31:53 +0000] «GET / HTTP/1.0» 200 83576
Никаких «-» «-» в конце нет, странно.
Какой лог ты анализируешь? nginx'a и дефолтный, не перенастраивал?
покажи кусок лога, с ддосерами
Апач и нгинкс валят лог в один и тот же файл. В нгинксе указана такая строка:
access_log /var/log/httpd/xyyandex-access.log main;
так не должно быть? ты для себя так настроил? в чем удобство?
ты настроил фильтр main прежде чем его юзать? при ребуте нгинкса ошибки есть?
Удобство в остутсвии стопицот мильёнов логов и присутствии всего одного.
Я думал, что main, это некий пресет, который уже настроен определённым образом.
alpha_Qu4z4r, ну и оставь один от nginx :)
Мой анализатор работает только с логом нгинска, не перенастроенным...
Если хочешь и свой чудо-лог оставить, то создай еще один только для nginx и юзай его в анализаторе!
крут. и вобще все на этом блоге круто =) так держать
Ага, спасибо :)
у меня заработало с одним равно
Илья, вы уверены что результат верный? Просто в основном, при
будет выполняться присваивание, и «if» получит от операции — TRUE