Предложение года Оплатите 1 месяц — получите 2 На все VPS и выделенные серверы, при любом сроке: оплачиваете 12 месяцев — сервер работает 24. Удвоить срок
Главная / Руководства по приватному хостингу / Защита VPS от DDoS: где заканчивается хостер и начинается уровень 7
Эксплуатация

Как пережить DDoS-атаку на свой VPS

Каждый тариф хостинга обещает «Защита от DDoS включена», и везде это означает одно и то же узкое: сеть поглощает флуды, измеряемые в гигабитах. Атаки, которые на самом деле кладут небольшие сайты, измеряются в запросах в секунду, стоят атакующему почти ничего и выглядят совершенно легитимно. Это руководство проводит границу между двумя видами атак, показывает, как за минуту понять, с каким из них вы столкнулись, и разбирает, что действительно держит оборону на той стороне границы, которая принадлежит вам.

Без KYC
Только крипто
Без логов
DMCA игнорируется
Полный root
NVMe SSD

Есть два момента, когда люди по-настоящему понимают, как работает защита от DDoS. Первый — спокойный, в момент покупки, когда в списке возможностей читаешь «Защита от DDoS включена» и молча предполагаешь, что эта фраза покрывает всё. Второй — в три часа ночи, когда сайт лежит, графики выглядят неправильно так, что это не укладывается в голове, а та самая включённая защита — правильно, и именно так, как задумано, — не делает вообще ничего.

Оба момента касаются одного и того же продукта и одной и той же истины: хостинг-провайдер фильтрует атаки, приходящие как чистый объём трафика, потому что именно он владеет каналом, по которому идут эти пакеты, а вы — нет. Он не может отфильтровать атаки, приходящие в виде обычных на вид запросов, потому что с точки зрения сети это и есть обычные запросы. Эта граница — между потоком, который поглощает ваш хостер, и потоком, который вам придётся пережить самостоятельно, — и есть тема всего материала. Всё, что дальше, — о том, как за минуту понять, по какую вы сторону этой границы, и что делать в каждом случае.

Два разных вида атак под одним названием

«DDoS» — это одно слово, которое покрывает две проблемы, не имеющие между собой почти ничего общего, кроме результата. Их останавливают в разных местах, разные люди, разными инструментами, и путаница между ними — причина того, что столько усилий по защите уходит не в тот уровень.

Объёмная — уровни 3 и 4Прикладная — уровень 7
Что приходитSYN-флуд, UDP-амплификация через открытые DNS-, NTP- или memcached-отражатели, ACK-флуд, обычный мусорный трафикОбычные HTTP-запросы: GET-флуд, POST-флуд, slow-loris, query-строки, обходящие кеш
Измеряется вГигабитах и миллионах пакетов в секундуЗапросах в секунду — часто всего в нескольких тысячах
Пропускная способность, нужная для вредаОгромная. Это состязание по ёмкости каналаПочти никакая. Хватит одного ноутбука, если эндпоинт достаточно дорогой
Где это нужно остановитьВыше по потоку, у вашего провайдера. К моменту, когда пакеты достигают вашего порта, ущерб уже нанесёнНа вашем сервере, вами самими — или на прокси перед ним, который вы контролируете
Как это выглядит на сервереИнтерфейс насыщен, счётчики пакетов зашкаливают, CPU может простаиватьСкромная полоса пропускания, но все воркеры заняты, нагрузка растёт, очередь к базе данных увеличивается
Кто это исправляетФильтрация трафика на стороне хостера, автоматически, обычно за секундыВаша конфигурация — ограничение частоты запросов, кеширование, потолки соединений

Перечитайте последние две строки ещё раз — именно в них практический смысл. Если интерфейс насыщен, ничто из того, что вы наберёте на сервере, не поможет: пакеты уже поглотили порт, и единственный, кто может их отбросить, — тот, кто владеет маршрутизатором выше по потоку. Если же интерфейс спокоен, а сайт всё равно не работает, верно обратное — ваш хостер не видит ничего плохого, потому что на его уровне действительно всё в порядке, а исправление целиком на вас.

Как пережить DDoS-атаку на свой VPS
Объёмные флуды фильтруются выше по потоку, там, где есть для этого ёмкость. То, что проходит сквозь этот фильтр, — обычный на вид трафик, и останавливать его — ваша задача, а не вашего хостера.

Что на самом деле покупает фраза «Защита от DDoS включена»

Защита на сетевом уровне реальна, ценна и почти всегда неправильно понимается. Когда провайдер заявляет о фильтрации L3/L4, это значит, что его сеть отслеживает трафик, идущий на ваш адрес, и при обнаружении флуда трафик перенаправляется через оборудование для очистки, которое отбрасывает вредоносную часть и пропускает дальше то, что выглядит легитимным. Это происходит без обращения в поддержку и обычно незаметно для вас, если не считать короткого сбоя.

За этой короткой фразой стоит немало, поэтому стоит разобрать, что она покрывает, а что нет:

  • Она покрывает атаки, которые вы не переживёте в одиночку. Флуд усиления на 200 Gbps против сервера с портом на 1 Gbps — это не вопрос настройки. Это арифметика. Фильтрация выше по потоку — единственный существующий ответ.
  • Она не имеет состояния относительно вашего приложения. Фильтр не знает, какие из ваших URL дорогие, какие посетители авторизованы, и что запрос к поисковому эндпоинту стоит в четыреста раз дороже запроса на логотип.
  • Она реагирует на порог, а не на ваши страдания. Обнаружение срабатывает по объёму трафика. Атака, которая никогда не пересекает порог, никогда его не запустит — независимо от того, насколько полно она уже положила ваш сайт.
  • В крайних случаях она может ненадолго увести адрес в null-route. У любой сети есть потолок. Если атака угрожает общей инфраструктуре, адрес может быть отключён на время — это стандартная, повсеместная практика, и о ней стоит знать заранее, а не в момент, когда это уже происходит.

Если коротко: ваш хостер защищает свою сеть, и вы от этого выигрываете. Он не защищает ваше приложение и не может этого делать. Уровень 7 — это не платная опция, которую от вас утаили, — это уровень, внутрь которого ваш провайдер не может заглянуть, не терминировав ваш TLS, а для тех, кто размещается офшорно, это сделка со своей серьёзной ценой.

Сначала выясните, атака ли это вообще

Внушительная доля предполагаемых DDoS-инцидентов на самом деле — нечто другое в чужом обличье, и способы исправления не взаимозаменяемы. Прежде чем включать какие-либо ограничения частоты запросов, потратьте две минуты на то, чтобы исключить самозванцев — ошибочный диагноз здесь стоит вам часа, а иногда и ваших реальных пользователей.

  • Вы стали популярны. Ссылка на крупном агрегаторе даёт форму трафика, которая выглядит точно как L7-флуд, — за исключением того, что referrer настоящие, а запросы идут на страницы, которые человек действительно хочет увидеть. Это проблема ёмкости со счастливой причиной; ограничивать её частоту — вредить самому себе.
  • Краулер потерял манеры. Агрессивные скраперы и боты для обучения ИИ способны без труда обогнать небольшой сервер. User-agent обычно выдаёт себя сам, и решение — robots.txt плюс точечное ограничение, а не общее.
  • Вы что-то сломали. Деплой, отключивший кеширование, взбесившаяся cron-задача, база данных, потерявшая индекс, — всё это выглядит как «внезапная нагрузка без очевидной причины». Если время совпадает с изменением, которое вы вносили, — верьте этому изменению.
  • Флуд создаёт ваш собственный мониторинг. Редко, стыдно и куда чаще, чем кто-либо готов признать. Цикл health-check, который повторяет попытки без backoff, способен создать по-настоящему впечатляющую частоту запросов.

Различающий вопрос прост: хочет ли этот трафик чего-то конкретного? У реальной нагрузки — даже выглядящей враждебно — есть форма. Она попадает на страницы, которые существуют, переходит по ссылкам, загружает ресурсы и приходит из правдоподобного набора сетей. Атака обычно этим не утруждается.

Читаем атаку прямо с сервера

Дашборд для классификации происходящего не нужен. Четыре команды, выполненные по порядку, за минуту скажут, на каком уровне вы сражаетесь, — а это определяет всё, что вы делаете дальше.

Канал забит? Следите за счётчиками интерфейса. Если пропускная способность упирается в потолок порта, вы имеете дело с объёмной атакой, и ваша задача — открыть тикет в поддержку, а не менять конфигурацию:

  • vnstat -tr 10 — средняя пропускная способность за десять секунд, самый быстрый честный показатель насыщения канала.
  • cat /proc/net/dev дважды с интервалом в секунду — разница пакетов и байтов по каждому интерфейсу, без дополнительных инструментов.

Это SYN-флуд? Полуоткрытые соединения скапливаются в состоянии SYN-RECV. Несколько штук — это нормально; тысячи — нет:

  • ss -s — сводная строка, количество соединений по состояниям одним взглядом.
  • ss -tn state syn-recv | wc -l — конкретное число, которое имеет значение.

Это уровень 7? Если полоса пропускания ничем не примечательна, а всё при этом медленно, посчитайте запросы на клиента в логе доступа. Один адрес с десятками тысяч обращений — это любитель; сто тысяч адресов по три обращения каждый — вот это уже серьёзно:

  • tail -n 100000 access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -30
  • Замените $1 на $7, чтобы вместо этого ранжировать запрашиваемые пути. Если доминирует один дорогой эндпоинт, вы нашли и цель атаки, и половину решения.

Что именно исчерпано? Load average сам по себе мало что скажет. Ищите конкретный потолок, в который вы упёрлись: все процессы PHP-FPM заняты, соединения с базой данных на пределе, файловые дескрипторы исчерпаны, либо воркеры зависли в состоянии D в ожидании диска. Именно этот потолок — а не трафик — положил сайт, и поднять его часто быстрее, чем что-либо фильтровать.

Держите это в уме, пока разбираетесь: если вы держите приватность-ориентированный сервис, именно во время атаки сильнее всего тянет включить расширенное логирование и оставить его включённым. Включите, если необходимо, но затем выключите обратно и агрессивно ротируйте файлы. Инцидент, после которого на диске остаётся месяц подробных логов посетителей, обменивает одну проблему на другую — худшую и более долгоживущую. Дисциплина, к которой это относится, разобрана в нашем руководстве по опсеку сервера.

Первые десять минут

Под давлением люди хватаются за самый большой доступный рычаг, и обычно это неверный выбор. Вот порядок действий, который ограничивает ущерб, — примерно от самого быстрого и безопасного к менее срочному:

  1. Сначала классифицируйте, потом действуйте. Насыщенный интерфейс означает объёмную атаку; спокойный интерфейс при занятых воркерах — уровень 7. Тридцать секунд здесь избавят вас от часа исправления не того уровня.
  2. Если это объёмная атака, немедленно откройте тикет и укажите адрес назначения, время начала и показания счётчиков интерфейса. После этого прекратите что-либо делать на сервере — изнутри это не исправить.
  3. Если это уровень 7, начните с кеша. Включить агрессивное полностраничное кеширование для анонимных посетителей — самый быстрый способ превратить простой в пожатие плечами, и это единственная мера, которая помогает и против реального трафика тоже.
  4. Затем — ограничение частоты запросов: сначала для целевого эндпоинта, потом для всего остального. Начинайте консервативно. Лимит, который выбивает ваших собственных пользователей, — это самим же собой продолженная атака.
  5. Блокируйте только то, что однозначно. Десяток адресов по сто тысяч запросов каждый, откровенно поддельный user-agent, одна страна, где у вас нет пользователей. Сопротивляйтесь желанию писать замысловатые правила под огнём — в следующем месяце вы их не вспомните.
  6. При необходимости осознанно сбрасывайте нагрузку. Статическая страница «идут технические работы» для неавторизованных посетителей удерживает сервер живым, держит API на ходу и покупает время на размышление. Лучше самому решить, чем жертвовать, чем позволить этому решиться за вас.
  7. Записывайте, что вы сделали. Каждое временное правило, которое вы добавили, — мина замедленного действия для вас же в будущем. Правила, которые помогли, становятся постоянными; остальные убираются завтра.

Ограничения, которые действительно держат, и ошибка, которую совершают все

Ограничение частоты запросов — основной инструмент против уровня 7, и nginx делает это хорошо с помощью двух директив, решающих две по-настоящему разные задачи. limit_req ограничивает частоту запросов — как часто клиент может обращаться. limit_conn ограничивает конкурентность — сколько соединений один клиент может держать открытыми одновременно. Флудам противостоит первая; slow-loris-атакам, которые держат тысячи почти неактивных соединений, чтобы исчерпать пул ваших воркеров, — вторая. Разверните только одну — и вы закрыты лишь от половины проблемы.

Три детали отличают ограничение, которое работает, от того, что существует лишь для вида:

  • Используйте burst и nodelay. Настоящие браузеры работают всплесками — один просмотр страницы порождает десяток почти одновременных запросов на ресурсы. Ограничение без запаса душит настоящих посетителей, пока атакующий, держащийся чуть ниже порога, проходит насквозь.
  • Ограничивайте дорогие эндпоинты отдельно. Страница поиска, форма входа, сброс пароля и любой эндпоинт, пишущий в базу данных, заслуживают куда более жёсткого бюджета, чем статические ресурсы. Атакующие находят их без всяких усилий, потому что именно они и причиняют боль.
  • Возвращайте 429, а не 503. Код состояния — это сигнал для добропорядочных клиентов и поисковых систем, что это ограничение, а не отказ, — и он не даёт неудачному дню превратиться в проблему с позициями в выдаче.

Ошибка, которая незаметно обнуляет всё это: если перед вашим сервером что-то стоит — CDN, балансировщик нагрузки, ваш собственный обратный прокси, — каждый запрос приходит с его адреса, а не адреса посетителя. Ограничение на клиента тогда считает весь интернет одним клиентом и либо не сработает вообще, либо разом забанит всю вашу аудиторию. Источник реального IP нужно настроить (в nginx — set_real_ip_from для диапазонов прокси плюс real_ip_header для заголовка, который он передаёт) прежде, чем ограничения обретут хоть какой-то смысл. Ограничьте это доверие диапазонами самого прокси: если довериться заголовку, который может прислать любой клиент из открытого интернета, атакующий сможет подделывать новую личность на каждый запрос и беспрепятственно проходить сквозь любое ваше ограничение.

Кеширование — самая дешёвая защита, которую вы когда-либо развернёте

Ограничение частоты отклоняет работу. Кеш делает так, что работы вообще не существует. Для всего, что видит анонимный посетитель, полностраничное кеширование меняет саму экономику атаки: запрос, который стоил бы обращения к базе данных, рендеринга шаблона и воркера PHP, превращается в чтение файла, измеряемое микросекундами. Тот же сервер, что падал при четырёхстах динамических запросах в секунду, отдаст десятки тысяч закешированных, даже не заметив этого.

Что важно, когда вы включаете это в разгар боя:

  • Кешируйте только для анонимных посетителей. Обход по cookie сессии. Отдать страницу одного авторизованного пользователя другому — куда худший инцидент, чем простой, который вы пытались устранить.
  • Осознанно отдавайте устаревшее содержимое. proxy_cache_use_stale в nginx вместе с updating error timeout означает, что, пока бэкенд испытывает трудности, посетители получают чуть устаревшую страницу вместо ошибки. Во время атаки это разница между сайтом, который выглядит нормально, и сайтом, который выглядит мёртвым.
  • Схлопывайте повторные промахи. proxy_cache_lock гарантирует, что тысяча одновременных запросов к одной и той же незакешированной странице породят один запрос к бэкенду, а не тысячу. Без этого атака, обходящая кеш, проходит сквозь него насквозь и обрушивается на вашу базу данных в полную силу.
  • Нейтрализуйте query-строки, обходящие кеш. Стандартный приём — добавить ? и случайное значение, чтобы каждый запрос стал уникальным ключом и промахивался вечно. Нормализуйте ключ кеша так, чтобы он игнорировал параметры запроса, которые ваше приложение на самом деле не использует.

Здесь есть приятная асимметрия, которую стоит усвоить: каждый час, потраченный на кеширование, заодно делает сайт быстрее в его лучший день, дешевле в эксплуатации и устойчивее к успеху. Почти ни одна другая линия обороны не приносит дивидендов, когда всё в порядке.

Потолки, которые решают, устоите вы или нет

Большинство серверов падают не потому, что кончился CPU. Они падают потому, что упираются в невидимый потолок, который никто сознательно не устанавливал, — значение по умолчанию десятилетней давности, имевшее смысл на железе, которым уже никто не пользуется. Под атакой первыми ломаются именно эти вещи:

  • Воркеры приложения. pm.max_children у PHP-FPM, количество воркеров Python, размер кластера Node. Это реальный предел конкурентности вашего сайта. Когда все они заняты, каждый следующий посетитель встаёт в очередь, и сайт лежит независимо от того, насколько простаивает CPU. Поднимайте это значение лишь настолько, насколько позволяет память, — уход в своп хуже, чем ожидание в очереди.
  • Очередь на приём. net.core.somaxconn и backlog прослушивающего сокета определяют, сколько соединений может ждать приёма. Маленький backlog превращает переживаемый всплеск в отказанные соединения.
  • SYN cookies. net.ipv4.tcp_syncookies позволяет ядру отвечать на SYN-флуд, не выделяя состояние для соединений, которые никогда не завершатся. Современные ядра включают это по умолчанию; проверьте это, а не считайте само собой разумеющимся, — это ничего не стоит и спасает от самого распространённого вида флуда.
  • Файловые дескрипторы. Каждое соединение — это дескриптор. Лимит nofile по умолчанию часто ниже, чем число соединений, которые вы пытаетесь обслужить, а режим отказа — accept проваливается, хотя всё выглядит здоровым, — по-настоящему сбивает с толку в три часа ночи.
  • Соединения с базой данных. Увеличение числа воркеров без увеличения пула соединений просто переносит очередь туда, где её труднее увидеть. Эти два числа нужно менять вместе.

Настраивайте это в спокойный день, а не во время инцидента. Смысл знать эти значения в том, что, когда сайт падает, вы можете назвать потолок, в который он упёрся, вместо того чтобы гадать, — а названный потолок можно исправить.

Ставим что-то перед источником

Всё описанное выше происходит на сервере. Следующий шаг — решить, должен ли сервер вообще напрямую принимать трафик. Есть три честных варианта, и правильный ответ зависит куда больше от того, что вы размещаете, чем от того, что вы можете себе позволить.

ПодходЧто вы получаетеЧего это стоит
Источник напрямую открыт, но защищёнПростота, отсутствие третьей стороны, отсутствие неподконтрольной вам терминации TLSВаш адрес публичен и постоянен. Уровень 7 — целиком на вас
Коммерческий CDN или сервис фильтрацииОгромная поглощающая способность, страница проверки в один клик, глобальное кешированиеКанал для жалоб с собственным мнением о вашем контенте, и компания, которая видит ваш трафик. Для офшорных или чувствительных к DMCA проектов это может стать самым слабым звеном в остальной аккуратно выстроенной схеме
Собственный фронт-узел — небольшой VPS с nginx, проксирующий на источник за файрволомПолный контроль, отсутствие третьей стороны на пути запроса, адрес, который можно сжечь и заменить, и реальный адрес, который остаётся скрытымСобственные пределы ёмкости и ещё одна машина, которую нужно поддерживать. Два-три фронта в разных сетях заметно усложняют задачу вывода из строя

Фронт-узел на собственной инфраструктуре заслуживает больше внимания, чем ему обычно достаётся, — особенно для тех, кто выбрал офшорный хостинг по причинам, которые крупному CDN могут быть не близки. Схема неброская: дешёвые прокси-узлы спереди, источник за файрволом, принимающий соединения только от этих узлов, DNS, указывающий на фронты. Если фронт атакуют, вы заменяете его новым адресом за минуты, а источник этого даже не замечает. Полная версия этой архитектуры — включая шесть способов, которыми исходный адрес всё равно утекает, — тема нашего руководства о скрытии IP исходного сервера.

Скрытый источник стоит дороже любого фильтра

Стоит сказать это прямо, потому что это переворачивает привычный порядок приоритетов: самая дешёвая доступная вам защита от DDoS — это адрес, которого нет у атакующего. Фильтрация — то, что вы делаете, когда это уже не сработало.

Это важнее, чем звучит, потому что исходные адреса утекают постоянно и незаметно. Исторические записи DNS с времён до того, как вы поставили прокси спереди, переживают это изменение на годы. Почта, отправляемая напрямую из приложения, несёт адрес в своих заголовках. TLS-сертификат, выпущенный на голый адрес, навсегда публикуется в журналах Certificate Transparency. Страница ошибки, редирект или малоприметный поддомен, который никогда не проксировался, — всё это выдаёт адрес. Если вы поставили CDN перед сервером, который раньше был открыт напрямую, считайте старый адрес известным, пока не смените его.

Следствие из этого — правило файрвола, и это самая ценная строка во всём руководстве: как только что-то встаёт спереди, источник должен отказывать в соединениях на портах 80 и 443 всем, кроме адресов этого фронта. Без этого прокси — лишь пожелание: любой, кто узнает реальный адрес, просто обходит его и атакует вас напрямую, а всё, что вы настроили на фронте, превращается в декорацию.

Выбор железа и локации, чтобы атаки оставались скучными

Часть этого решается ещё до того, как случится атака, — в момент выбора тарифа. Три свойства значат куда больше, чем предполагает спецификация:

  • Безлимитный трафик. На тарифе с учётом трафика атака — это не только простой, но и счёт. Трафик, который вы не запрашивали и не могли отклонить, всё равно засчитывается в лимит. Безлимитная передача данных превращает финансовый риск в чисто технический — а это куда более приятный класс проблем.
  • Ваш ли это порт. На общем виртуализированном хосте атакованный сосед может ухудшить и вашу работу, а ваш собственный потолок защиты — общий с другими. Выделенное железо с собственным портом убирает оба эффекта. Для проекта, который ожидает враждебное внимание, это самая очевидная причина перейти с VPS на что-то большее — весомее, чем количество ядер или объём RAM.
  • Где физически находится сеть. Хорошо связанная европейская сеть с реальной транзитной ёмкостью поглотит флуд, который плохо связанная сеть — нет, и юрисдикция, выбранная по юридическим причинам, тоже обладает сетевыми характеристиками. Стоит проверить оба этих момента при выборе среди доступных локаций.

Есть и аргумент масштаба, который незаметно играет в пользу простоты. Статический сайт за кешем на скромном сервере крайне сложно положить; тот же контент на тяжёлой CMS с некешируемым поисковым эндпоинтом может сломать один упорный человек со скриптом. Уменьшение доли динамики — это тоже защита, и она бесплатна. Если ваш проект действительно живёт под постоянной нагрузкой, вопрос выбора конфигурации под неё раскрыт в наших заметках о хостинге для высоконагруженных проектов.

Пять вещей, которых не стоит делать

Здесь сценарии провала достаточно устойчивы, чтобы их перечислить, и каждый уже стоил кому-то выходных:

  • Не отправляйте в null-route себя сами. Заблокировать собственный адрес — значит закончить атаку самым буквальным способом из возможных: до вас больше не сможет достучаться никто, включая ваших пользователей. Это инструмент последней надежды для вашего провайдера, а не действие, которое вы предпринимаете добровольно.
  • Не считайте fail2ban защитой от DDoS. Это хороший инструмент против перебора с нескольких адресов. Против распределённого флуда он реагирует за минуты на то, что происходит за секунды, а правило, банящее тысячи адресов, может обойтись обработке файрвола дороже, чем сама атака.
  • Не платите выкуп. Подавляющее большинство писем с вымогательством, угрожающих разрушительной атакой, приходят от людей без каких-либо возможностей, рассылающих тысячи одинаковых сообщений. То меньшинство, что способно исполнить угрозу, вернётся снова, потому что вы уже доказали, что платите.
  • Не мстите. Помимо того, что это незаконно практически везде, источники атаки — скомпрометированные третьи стороны. Вы будете атаковать жертв, причём с адреса, однозначно принадлежащего вам.
  • Не переезжайте в панике. Смена хостинга посреди атаки означает, что новый адрес станет публичным за считаные минуты, а рабочей конфигурации у вас ещё нет. Сначала стабилизируйтесь, переезжайте осознанно потом — а если решите переехать, наше руководство о переезде без простоя существует именно для того, чтобы переезд не стал вторым инцидентом.

Коротко

Без рассуждений рабочая модель умещается в восемь пунктов:

  1. Сначала классифицируйте. Насыщенный интерфейс означает объёмную атаку и относится к вашему хостеру. Спокойный интерфейс с исчерпанными воркерами означает уровень 7 и относится к вам.
  2. Для объёмной атаки заведите тикет с адресом, временной меткой и вашими счётчиками — а затем перестаньте трогать сервер.
  3. Агрессивно кешируйте для анонимных посетителей, отдавайте устаревшее содержимое под нагрузкой и схлопывайте повторные промахи. Это изменение с наибольшей отдачей из всех, что вы можете внести.
  4. Ограничивайте и по частоте запросов, и по конкурентности, жёстче всего — на самых дорогих эндпоинтах, и возвращайте 429.
  5. Прежде всего этого настройте определение реального IP, иначе любое ограничение на клиента за прокси окажется либо бесполезным, либо катастрофическим.
  6. Знайте свои потолки — воркеры, backlog, дескрипторы, соединения с базой данных — и поднимайте их осознанно в спокойный день.
  7. Держите адрес источника в секрете и за файрволом, открытым только для ваших фронт-узлов. Это стоит дороже, чем все фильтры вместе взятые.
  8. Берите безлимитный трафик, чтобы незапрошенный трафик никогда не оборачивался ещё и счётом.

Ничто из этого не делает вас неуязвимым, и всякий, кто продаёт неуязвимость, продаёт нечто иное. Это лишь выводит вас из категории тех, кого укладывает офлайн заскучавший подросток, и переводит в категорию тех, для чьего беспокойства нужны настоящие ресурсы и настоящее намерение, — а для подавляющего большинства проектов это неотличимо от полной безопасности. Всё остальное — та же неброская работа, которая делает сервер хорошим во всём остальном: защищённым с первого дня, восстановимым в худший из них, и работающим там, где к вашему трафику относятся как к вашему делу.

FAQ

DDoS на небольшом сервере — частые вопросы

01 Значит ли фраза «Защита от DDoS включена», что я защищён от всего?

Нет, и пробел здесь вполне конкретный, а не расплывчатый. Включённая защита — это фильтрация на сетевом уровне: она отбрасывает объёмные флуды — SYN-флуд, UDP-амплификацию, потоки мусорных пакетов — ещё до того, как они достигнут вашего порта. Это именно та категория, с которой вы объективно не справитесь в одиночку, поэтому её и включают по умолчанию. Она не анализирует ваше приложение, поэтому HTTP-флуд в несколько тысяч запросов в секунду по дорогому эндпоинту проходит сквозь неё нетронутым и кладёт сайт, пока все сетевые графики выглядят нормально. Уровень 7 — это конфигурация, за которую отвечаете вы сами: кеширование, ограничение частоты запросов и потолки соединений.

02 Как отличить DDoS-атаку от всплеска трафика?

Спросите себя, хочет ли этот трафик чего-то конкретного. Реальные посетители — даже внезапным потоком с популярной ссылки — запрашивают существующие страницы, подгружают их ресурсы, приходят с правдоподобными referrer и распределены по множеству сетей естественным образом. Атака обычно долбит по одному пути, игнорирует ресурсы, шлёт неправдоподобные или отсутствующие user-agent и показывает распределение, которое выглядит синтетическим. Проверьте лог доступа на количество запросов по адресу клиента и по пути: если доминирует один эндпоинт и больше ничего не загружается — это атака. Если отдаются те же страницы, которые захотел бы увидеть человек, а referrer настоящие, у вас проблема с ёмкостью и счастливой причиной для неё.

03 Какое единственное действие даёт наибольший эффект во время атаки?

Включить полностраничное кеширование для анонимных посетителей и настроить отдачу устаревшего содержимого, когда бэкенд испытывает трудности. Ограничение частоты запросов отклоняет работу; кеш делает так, что работы вообще не возникает. Запрос, который стоил бы обращения к базе данных, рендеринга шаблона и воркера приложения, превращается в чтение файла, и то же самое железо, что падало при паре сотен динамических запросов в секунду, отдаст десятки тысяч закешированных. Это также единственная мера из всего списка, которая одинаково помогает и против реального трафика, поэтому, в отличие от ограничения частоты запросов, она не может ударить по вашим же пользователям.

04 Почему моё ограничение частоты запросов в nginx перестало работать после того, как я поставил CDN спереди?

Потому что теперь каждый запрос приходит с адреса CDN, а не посетителя, и ограничение на клиента считает весь интернет одним клиентом. В зависимости от порога оно либо никогда не сработает, либо разом забанит весь ваш трафик. Настройте источник реального IP — в nginx это доверенные диапазоны прокси плюс заголовок, который прокси передаёт, — чтобы ограничение снова ориентировалось на настоящего посетителя. Ограничьте это доверие диапазонами самого прокси: если принимать заголовок, который может подставить любой клиент из открытого интернета, атакующий сможет подделывать новую личность на каждый запрос и проходить сквозь любое ваше ограничение.

05 Достаточно ли fail2ban, чтобы остановить DDoS-атаку?

Нет. fail2ban читает логи с интервалом и банит адреса-нарушители после превышения порога, что подходит против перебора с небольшого числа источников. Распределённая атака приходит за секунды с тысяч адресов, каждый из которых шлёт лишь горстку запросов, поэтому порог никогда не достигается, а время реакции в любом случае слишком велико. Хуже того, набор правил, разросшийся до десятков тысяч записей, может потреблять больше ресурсов, чем сама атака. Оставьте fail2ban для SSH и эндпоинтов входа, а с флудами боритесь кешированием, ограничением частоты запросов и фильтрацией выше по потоку.

06 Стоит ли использовать CDN или лучше запустить собственный обратный прокси спереди?

Это зависит от того, что вы размещаете, а не от вашего бюджета. Коммерческий CDN даёт поглощающую способность, с которой вам не сравниться, и страницу проверки в один клик, но вместе с ним вы наследуете его канал для жалоб, и он видит ваш трафик — а для офшорных или чувствительных к DMCA проектов это часто самое слабое звено в остальной аккуратно выстроенной схеме. Собственные фронт-узлы требуют больше работы и имеют реальные пределы ёмкости, зато в пути запроса нет третьей стороны, а атакованный фронт можно заменить новым адресом за минуты. В любом случае источник должен быть закрыт файрволом так, чтобы принимать веб-трафик только от фронта, — иначе вся схема превращается в декорацию.

07 Обойдётся ли атака мне ещё и в деньги, а не только в простой?

На тарифе с учётом трафика — да: трафик, который вы не запрашивали и не могли отклонить, всё равно засчитывается в лимит, а затяжной флуд способен породить счёт за перерасход больше, чем стоимость года хостинга. Это и есть практическая причина, по которой безлимитный трафик значит куда больше, чем кажется по строчке в спецификации: он превращает финансовый риск в чисто технический. Стоит также знать заранее, что если атака угрожает общей инфраструктуре, провайдеры могут временно отправить адрес в null-route — это стандартная повсеместная практика, а не сбой именно у вашего хостера.

08 Повышает ли переезд на офшорный или no-KYC хостинг вероятность атак?

Сам по себе выбор хостинга нейтрален; внимание привлекает то, что вы на нём размещаете. Игровые серверы, форумы, стриминг, маркетплейсы и всё, у чего есть конкурент или недоброжелатель, притягивают атаки независимо от юрисдикции. Что действительно меняется офшорно — это ваши гарантии: вас с меньшей вероятностью отключат за неудобство, и у этого есть обратная сторона — защита здесь техническая, а не договорная. Выбирайте локацию с реальной транзитной ёмкостью, берите безлимитный трафик, держите адрес источника скрытым и относитесь к уровню 7 как к своей ответственности с первого дня, а не с первого инцидента.

Разместите сервер там, где флуды фильтруют за вас

Офшорные KVM-серверы в семи юрисдикциях с L3/L4-фильтрацией DDoS, безлимитным трафиком, полным root-доступом и NVMe-накопителями. Без KYC, оплата криптовалютой, развёртывание через минуты после подтверждения транзакции.

Тарифы VPS Выделенные серверы Офшорный хостинг