14 heures d'enfer, ou comment nous avons combattu une attaque DDoS massive contre une boutique en ligne fédérale
13 февраля, в прошлую пятницу, на одного из наших заказчиков началась DDoS-атака.
DDoS – это когда боты непрерывно заходят на сайт с целью «положить» сервер.
Обычно такое заказывают недобросовестные конкуренты, чтобы отключить сайт, например, накануне праздника.
Текст ниже от нашего техдира, который собственно и защищал грудью сайт клиента
—
День начался не с кофе. С 7 утра и до 9 вечера мы плечом к плечу со штатным сисадмином компании рубились за выживание сайта samura.ru. Мы победили, но это был по-настоящему эпичный бой.
Волна 1: Проверка на прочность (Утро)
Вообще, небольшие DDoS-атаки на Самуру — дело регулярное, и мы всегда отбивали их без особых проблем точечными банами в iptables.
Вчера утром мониторинги снова взвыли. Сайт начал отдавать 502, в netstat висело 13 000 необработанных соединений в очереди сервера. Мы быстро «подзакрутили гайки» в Nginx, отсекли большую часть IP-шников ботов, графики поползли вниз. Выдохнули. Как оказалось — слишком рано.
Волна 2: Умные боты и удар по больному (День)
Атакующие поняли, что в лоб нас не взять, сменили тактику и начали бить тяжелыми запросами в бэкенд (Bitrix/Apache), обходя простые лимиты и сменив свои IP адреса. Процессоры улетели в 100% полку.
В ход пошли уже суровые баны целыми IP-диапазонами в iptables. Жесткие лимиты через limit_conn и limit_req. Параллельно жестко ограничили количество рабочих процессов Apache (MaxRequestWorkers), чтобы спасти оперативку (у нас 17 ГБ, и отдавать всё ботам мы не собирались). Сервер перестал падать в обморок, но шторм только усиливался.
Волна 3: Пробой брони и 43 000 соединений (Вторая половина дня)
Боты пошли на крайность. Проблема была не просто в том, что они били напрямую по IP сервера (мы в процессе даже успели сменить IP-адрес, они быстро сместили атаку на новый), а в том, что ботнет разрастался в геометрической прогрессии.
Банить через iptables стало малоэффективно: от каждого вредоносного IP шло всего по 5-7 запросов — неотличимо от обычных пользователей.
Но их было безумно много, из самых разных подсетей. Дошло до 43 000 единовременных коннектов. И тут стало ясно, что ресурсы самообороны нашего сервера – исчерпаны, нам срочно нужна была тяжелая артиллерия.
️ Эпичный финал: Призыв кавалерии (Вечер)
Как только стало понятно, что своими силами на уровне сервера этот объем ботов нам не отсеять и не переварить — началась нервная гонка по выбору облачной DDoS-защиты. Вместе с сисадмином начали экстренно перебирать сервисы из тех, с кем работали раньше и новых.
Выбирали из нескольких сервисов: часть отвечала вечность (а у нас счет на минуты!), сайты других вообще не вызывали доверия. В итоге остановились на ребятах, которые ответили оперативно и показались максимально адекватными. Ударили по рукам и полетели настраивать.
Дальше была техническая рутина: прописывание десятков подсетей защиты в белый список фаервола и тотальный DROP для всех остальных. Настройка set_real_ip_from в Nginx (чтобы сервер наш не банил саму защиту, принимая её за одного гигантского бота).
И, конечно, ловля багов с внутренними соединениями и трафиком от маршрутизатора, редиректами и обновлением А-записей на новый защищенный IP. Сохранение на память 7Гбайтного файла access.log и его очистка, чтобы облегчить жизнь серверу после такой встряски.
Conclusion :
В 21:00 мы ввели финальную команду iptables-save. Load Average замер на идеальных 0.66. Оперативка в норме. Сайт снова летает.
Устали дико, будто разгружали вагоны. Но это невероятное чувство, когда ты шаг за шагом переигрываешь атакующих и возвращаешь проект к жизни.
Щиты подняты. Работаем дальше! ⚔️