Коротко о нас.
Совместно с Центром телекоммуникаций и информационных технологий МГУ им. М.В. Ломоносова, мы занимаемся исследованиями DDoS.
Основная цель: разработать и донести до сообщества эффективные, доступные техники противодействия распределенным атакам на отказ в обслуживании.
В рамках исследовательской программы мы бесплатно предоставляем защиту. Все что нужно — передать трафик на наше оборудование любым удобным способом (изменить А запись DNS, GRE/IPIP tunnel).
В блоге проекта hll.msu.ru мы будем регулярно публиковать материалы, полученные в ходе исследований. Самые интересные случаи, методики, распространенные ошибки, — публиковать на Хабре.
В прошлую пятницу наблюдали ситуацию, в которой вполне вменяемый админ, к которому зашли в гости около 7 тыс ботов и, видимо, не очень радостный директор,
поддался панике и соорудил конструкцию вида:
NGINX -> apache -> mod_php -> memcached -> [кэшированая версия /]
Это бесспорно лучше чем генерация титульной страницы на каждый запрос с несколькими выборками для базы, но все еще недостаточно хорошо…
Настолько нехорошо, что даже те 3-8 запросов которые успевал сделать бот, до того как был распознан и забанен, создавали серьезные проблемы и время обработки запросов сервером составляло 1-2 секунды.
Вспомнив пару интересных новых “тематических” фич которые проходили за последних месяцев в NGINX, решили поупражняться в config-fu и в итоге получился вот такой вот забавный этюд…
http {
# даже обычные медленные клиенты, обычно дороги
reset_timedout_connection on;
client_header_timeout 15;
client_body_timeout 15;
send_timeout 5;
keepalive_timeout 30 15;
# введем две зоны ограничений.
# По открытым соединениям и по request rate
limit_req_zone $binary_remote_addr zone=qglob:16m rate=3r/s;
limit_zone cglob $binary_remote_addr 16m;
server {
listen 80;
server_name www.myhost.ru;
proxy_set_header Host $host;
# необходимо для работы proxy_store
proxy_buffering on;
# ограничим максимальное количество соединений с одного ip
# до 4х клиентов с одного ip по rfc2616
limit_conn cglob 32;
# Быстро отлавливаем “GET / “.
# Дописываем удобное имя файла.
location = / {
rewrite ^/$ /index.html last;
}
#Пост-рейт отдача статического index.html или загрузка с бэкенда.
location = /index.html {
internal;
open_file_cache_errors off;
limit_req zone=qglob burst=9 nodelay;
root /tmp/nginx/cache/;
error_page 404 = /cached$uri ;
}
location /cached/ {
internal;
alias /tmp/nginx/cache/;
proxy_pass phpfarm;
proxy_store on;
proxy_store_access user:rw group:rw all:r;
proxy_temp_path /tmp/nginx/tmp/;
}
#Жестоко зажатый на два запроса в секунду поиск.
location = /advanced_search_result.php {
limit_req zone=qglob burst=2;
proxy_pass phpfarm;
}
# И все остальное.
location / {
proxy_pass phpfarm;
}
}
}
Далее 5 минутный TTL на коленке…
nohup `while true; do rm -f /tmp/nginx/cache/index.html; sleep 300; done`&
Что было необходимо и достаточно чтобы остановить 5000 ботов.
В качестве дополнительной меры можно выбирать наиболее назойливых по limiting requests из error_log и отправлять их в Null либо на ближайшем раутере либо в вашем netfilter.
Подумать:
Переработав этот конфигурацианный файл можно организовать и полное кэширование вашего сайта. Попробуем?
Хорошим тоном считается что все сервисы, и LAMP в том числе, на сервере стартуют сразу после его перезагрузки автоматически… И автоматически укладываются DDoS ом вместе с сервером.
Возможно стоит выбрать другую стратегию для initrc?
В случае например с NAT beeline огромное количество людей может находиться за одним IP, но если вы не yandex.ru разумно предположить что 8 пользователей beeline на вашем сайте это достаточно?
Почитать:
NGINX proxy module.
Дырявые ведра или что такое burst?
Поучаствовать:
Программистам client-side js/ajax и c/c++ разработчик-искусственный интеллект, системы принятия решений — mailto://flx@msu.ru
https://habrahabr.ru/company/highloadlab/blog/68557/
Это простой но эффективный способ отбиться от простой атаки. NGINX очень популярен. DDoS очень популярен. Вот они и нашли друг-друга.
Есть как минимум еще несколько способов добиться такого-же результата с помощью NGINX, и возможно они будут чуть лучше и быстрее.
Это не абсолют, это всего-лишь «путевые заметки». Пусть и с комментариями.
proxy_store нашли более «легким».
Как то у вас странно, объявлено
limit_req_zone $binary_remote_addr zone=qglob:16m rate=3r/s;
а в limit_zone используется qulag
И кроме того burst это параметр всплеска относительно ограничения в rate, который будет задержен а не отброшен
Вообще было-бы крайне разумно на frontend сформулировать разумные query rate политики для различного рода трафика, предупредительно разложив элементы веб-приложения в различные зоны в зависимости от их «стоимости». Статика, простые скрипты и, например поиск.
Ну обычно так и делается. Еще не плохо было бы если фронтенд имеет прямой доступ к статике.
Просмотров: 1111