В прошлую пятницу наблюдали ситуацию в которой вполне вменяемый админ, к которому зашли в гости около 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;
limit_req zone=qglob burst=9 nodelay;
open_file_cache_errors off;
root /tmp/nginx/cache/;
error_page 404 = /cached$uri ;
}
location /cached/ {
internal;
alias /tmp/nginx/cache/;
proxy_pass http://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=qulag burst=2;
proxy_pass http://phpfarm;
}
# И все остальное.
location / {
proxy_pass http://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 пользовтелей билайн на вашем сайте это достаточно ?
Что огорчило админа больше ? Боты или Директор ?
Почитать еще:
Дырявые ведра или что такое burst?



1 расширить и отюнить ядро для обработки соеденений и работой с нджинксом
2 обойтист без апача (Fastcgi)
дополнение для пакетных забивок
1 норошие сетевушки (интел) для режима поллинга
2 грамотная настройка PF c баном
3 А если совсем тяжело то пару серверов и кластер PF (CARP) и не надо не какой циски-гуард
укладываются по полосе пропускания провайдера?
видимо в вашей конфигурации система уходила в своп и отзывчивость исчезала. Надо лимитировать количество обработчиков у apache чтобы хватало памяти.
1. Вдумчиво проставленный ServerLimit вовсе не гарантирует того что к вам не прийдет OOM, особенно если у вас mod_php и какой-нибудь акселератор.
2. swap для веб-приложения - вещь скорее вредная, чем бесполезная.
3. пока на один запрос стоимостью N, будет выполняться действий на N^10 - есть много других не менее забавных способов отсечь администратора от доступа посредством ssh, а возможно и посредством KVM.
4. смысла поднимать apache всеравно не очень много - зачем он если ваш db layer скорее всего в рассыпавшемся состоянии ?
Все это - простые и очевидные мысли, лежащие на поверхности.... .... о которых почему-то очень часто забывают.
route add banned_ip blach_hole_destination_ip metric