|
Еще один вариант защиты от DDoS посредством nginx-модуля testcookie. |
Статьи |
|
|
|
Существует сторонний nginx-модуль testcookie-nginx-module. Модуль умеет ставить cookies стандартным способом через HTTP-заголовок Set-Cookie, после установки перенаправляет пользователя, используя код ответа 301 и заголовок Location или используя код ответа 200 и HTML тег Meta «refresh». Он также может считать количество попыток поставить cookies и отправлять пользователя по заданному URL после превышения максимального количества неудачных попыток. Вариант реализации: После установки cookie делается редирект на текущий url с параметром label_XYZ=1, если после редиректа запрос пришел без cookie, делается повторный редирект на текущий url с параметром label_XYZ=2 и так 3 раза. При четвертом обращении без cookie отдается ответ 403. Можно конечно использовать limit_req/limit_zone, но есть небольшие минусы: - усложненная реализация белых списков; - упрощенные методы отлова и распознания "злодеев"; Но и у testcookie также есть свои минус, он является сторонним модулем и не идет в официальном дистрибутиве (в Gentoo это не проблема, существующий ebuild был переписан в течение часа). Сборку модуля в nginx я пропускаю, т.к. для каждого дистрибутива и пакетного менеджера это отдельная история. Переходим к настройке. Основная настройка сводится к правке nginx.conf, где особое внимание уделяется параметрам testcookie_secret и testcookie_arg. Генерируем значения самостоятельно. Входные строки можно брать любые, главное получить на выходе славный набор символов. # echo label |md5sum 41cc0e4945e162021cfdd993f4c1104d - # echo defcon |md5sum 15dbedaeabc7f0c09f0fe834e4a3b46a - Полученные значения подставляем в качестве аргументов для testcookie_secret и testcookie_arg. значение для testcookie_name также можно установить произвольное. # vi /etc/nginx/nginx.conf http { ... testcookie off; testcookie_name XSAE; testcookie_secret 15dbedaeabc7f0c09f0fe834e4a3b46a; testcookie_session $remote_addr; testcookie_arg label_41cc0e4945e162021cfdd993f4c1104d; testcookie_max_attempts 3; testcookie_get_only on; testcookie_internal off; # используем белые списки include /etc/nginx/testcookie_whitelist.conf; ... } Создаем движок rewrite'ов в /etc/nginx/testcookie.conf Cуть в следующем, необходимо делать реврайт конечного урла, не делать это так чтобы не светился параметр редиректа (?label_*) # vi /etc/nginx/testcookie.conf set $do_rewrite 0; # проверяем наличие выданной куки if ($http_cookie ~ "XSAE=[0-9a-f]+") { set $do_rewrite 1; } # если в аргументах присуствует метка выданная модулем, выкусываем её if ($args ~ "^((.*)(label_41cc0e4945e162021cfdd993f4c1104d=1&|&label_41cc0e4945e162021cfdd993f4c1104d=1(.*))|label_41cc0e4945e162021cfdd993f4c1104d=1)$") { set $target "$2$4"; set $do_rewrite "1${do_rewrite}"; } # делаем правильный реврайт, подставляем только урл и другие возможные параметры (без метки) if ($do_rewrite = 11) { set $args $target; rewrite ^.*$ http://$host$uri break; } Белый список (для краткости сократил до двух адресов) # vi /etc/nginx/testcookie_whitelist.conf testcookie_whitelist { # Yandex 77.88.0.0/18; 87.250.224.0/19; } изменения в /etc/nginx/proxy_headers.conf # vi /etc/nginx/proxy_headers.conf testcookie on; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; Затем в каждый из конфигурационных файлов виртуальных хостов прописываем в начало секции server. Таким образом в каждом виртуальном хосте мы подгружаем rewrite-движок, и белые списки. Сам механизм testcookie будет работать в случаях когда запросы проксируются на бэкенды и подгружается proxy_headers.conf server { ... include /etc/nginx/testcookie.conf; include /etc/nginx/testcookie_whitelist.conf; ... # пример локейшена location / { include /etc/nginx/proxy_headers.conf; proxy_pass http://upstream; } Перезапускаем. # nginx -t -c /etc/nginx/nginx.conf # /etc/init.d/nginx restart Каким образом проверить? Выбираем url который точно отдастся в бэкенд и отдаем его curl или wget # curl -s -L -I http://serversite.dom/link # wget --no-cookie http://serversite.dom/link Ниже пример проверки рабочей конфигурации:
Видим что нам дают редирект и выдают куку, но мы игнорируем куку и на третью попытку получаем 403 Forbidden. Как мониторить и в случае чего забанить? Используем скрипт в кроне (перезапуск iptables для того если мы баним iptables'ом злодеев) # crontab -e */5 * * * * /root/bin/testcookie-search.sh Сам скрипт #!/bin/sh NGINX_LOG="/var/log/nginx/acceess.ru-access_log" DEBUG_LOG="/var/log/testcookie/$(date +"%Y%m%d-%H:%M").log" LABEL="label_41cc0e4945e162021cfdd993f4c1104d=3 .* 403" MAILTO="mail@mail.com" ALL="/tmp/all" BORED="/tmp/bored" THRESHOLD=15 if [ ! -f /tmp/offset ]; then echo "offset file not found. create it. restart script after 1 minute." stat -c '%s' "$NGINX_LOG" > /tmp/offset; exit fi echo "" > $ALL if $(stat -c '%s' "$NGINX_LOG") -lt $(cat /tmp/offset) 2>/dev/null then echo 0 > /tmp/offset fi tail -c +$(cat /tmp/offset) "$NGINX_LOG" |grep -E "$LABEL" |cut -d' ' -f1 |sort |uniq -c |sort -nk1 > $ALL stat -c '%s' "$NGINX_LOG" > /tmp/offset if [ ! -z "$ALL" ]; then while read reqs addr; do if [ $reqs -ge $THRESHOLD ]; then # /sbin/iptables -I INPUT -s $addr -p tcp -m tcp --dport 80 -j DROP # /sbin/iptables -I INPUT -s $addr -p tcp -m tcp --dport 80 -m limit --limit 6/min --limit-burst 10 -j ACCEPT echo $reqs $addr >> $BORED fi done < $ALL if [ ! -z $BORED ]; then echo "Suspicious ip-addresses. $(cat $BORED)" | mail $MAILTO ; fi cat /dev/null > "$BORED" &> /dev/null fi В скрипте закоментированы строки которые позволяют сходу добавлять "злодеев" в iptables. Скрипт парсит лог nginx'а за последние 5 минут, на предмет наличия шаблонной строки, по которой можно определить что клиенту выдали 403. В ходе формируется список с такими клиентами, и в самом конце формируется письмо содержащее список злодеев превысивших планку определенную в THRESHOLD и отправляется на указанную в MAILTO почту. Вот собственно и все. Важно следить и своевременно обновлять whitelist'ы чтобы туда не попадали поисковые боты, площадки CDN если таковые используются и т.п.
|
Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь. Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем. |
|
Автор: hellevil | 19-08-2014, 10:39 | Просмотров: 6 609 |
|
|
|
|