Позавчера днем от от одного из клиентов поступило обращение с жалобой на то, что его интернет-магазин перестал работать, а веб-сервер выдавал сообщение «500 Internal Server Error». Через полчаса сервер перестал быть доступен и не реагировал на подключения по http, ftp и ssh. После перезагрузки сервера обнаружилось, что закончилось все дисковое пространство, хотя еще неделю назад было свободно несколько гигабайт.
Стоит немного сказать о характеристиках системы, которая обслуживает сайт. Интернет-магазин работает на VPS (виртуальный сервер) со средними параметрами: одно ядро процессора 1ГГц, 1Гб оперативной памяти, 10 Гб дискового пространства. На сервере настроена связка nginx+Apache (nginx отдает статичный контент и проксирует запросы на Apache), установлен eAccelerator, сам интернет-магазин работает на 1С-Битрикс.
Поиски причин, почему закончилось место, привели в папку с логами nginx, которые в совокупности стали занимать 4 Гб. Анализ содержимого логов указал на то, что на сайт ведется DDoS-атака. Характер запросов был Request: "GET / HTTP/1.1" с разных ip-адресов. Интенсивность атаки составляла порядка 15 тысяч запросов в минуту.
Стали думать, что делать в такой ситуации. В первую очередь были выключены процессы apache, nginx, освобождено место и отключено логгирование в nginx:
error_log off; access_log off;
Дальше попробовали запустить nginx и Apache. Поведение системы выявило, что «умирает» в первую очередь Apache, при этом nginx обслуживал запросы и работал стабильно. Эти данные навели на мысль, что можно организовать конфигурацию системы таким образом, чтобы запросы атакующих ботов не проходили до Apache и резались на уровне nginx без использования специальных сетевых фильтров с применением black-листов. Конфигурация получилась следующая.
Файл index.php в корне сайта, который обслуживал запросы к главной странице, был переименован в index2.php. В корень сайта был добавлен файл index.html с содержимым:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="refresh" content="0; url=http://www.site.ru/index2.php">
</head>
<body></body>
</html>
В настройки nginx было добавлено правило обработки запросов к главной странице:
location = / {
index index.html;
}
location ~* \.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|docx|xls|xlsx|exe|pdf|ppt|pptx|txt|tar|wav|mp3|bmp|rtf|js|swf|html)$ {
root /home/webmaster/site.ru/web;
access_log off;
expires max;
}
Данная конфигурация работает следующим образом. Веб-сервер nginx на все запросы к главной странице быстро отдает файл index.html. Если к сайту обратился бот, то таким образом его запрос не доходит до Apache. Если это оказался обычный пользователь, то браузер в соответствии с правилами редиректа, указанными в index.html, сразу же перенаправит пользователя на реальную главную страницу, расположенную нами по адресу http://www.site.ru/index2.php. После этого пользователь сможет спокойно работать с сайтом.
Дальнейший мониторинг показал, что конфигурация оказалась вполне работоспособной и работает при этом стабильно. Общая нагрузка на процессор не превышала 30-40% и все благодаря производительной работе отечественного веб-сервера nginx. Отмечу, что данное решение не универсальное и подходит только для случаев массовой атаки на определенную страницу сайта. Как правило, такой страницей оказывается на главная. Существует еще множество разновидностей DDoS-атак, для каждой из которых следует вырабатывать свой индивидуальный способ борьбы.
