Блог компании 3v-Hosting

Настройка rate limiting в Nginx для защиты от простого DDoS

Администрирование

7 мин.


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

Снизить такую нагрузку можно довольно простым способом. Для этого в веб-сервере Nginx есть механизм rate limiting, который ограничивает частоту запросов от одного клиента. Полноценную защиту от DDoS он, конечно, не заменит, но способен отсеять заметную часть нежелательного трафика ещё на уровне веб-сервера. До приложения эти запросы уже не дойдут, а значит, процессор, память и другие ресурсы будут расходоваться гораздо экономнее.

 

 

 

 

Что такое rate limiting

Rate limiting - это ограничение числа запросов, которые один клиент может отправить за определённый промежуток времени. Обычно Nginx отслеживает клиентов по IP-адресу, хотя при необходимости можно использовать и другие параметры.

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

Такой механизм помогает в самых разных ситуациях. Например, он снижает эффекты от:

  • простых HTTP Flood-атак;
  • попыток перебора паролей;
  • автоматического сканирования сайта ботами;
  • слишком агрессивных парсеров.

 

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

 

 

 

 

Как работает ограничение запросов в Nginx

Механизм ограничения запросов в Nginx строится вокруг двух директив: limit_req_zone и limit_req. Первая задаёт зону памяти, где сервер хранит информацию о том, как часто каждый клиент обращается к сайту.

Например:

limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

 

Здесь используется несколько параметров:

  • $binary_remote_addr - это идентификатор клиента, которым обычно становится его IP-адрес в двоичном формате;
  • zone=api_limit:10m - это имя зоны и объём памяти, выделенной для хранения статистики;
  • rate=10r/s - лимит в десять запросов в секунду для каждого клиента.

 

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

Например:

location / {
    limit_req zone=api_limit burst=20 nodelay;
}

 

Тут появляются ещё два параметра.

  • burst=20 - разрешает кратковременное превышение основного лимита. Это полезно в обычной работе сайта, так как браузер редко загружает страницу одним запросом и обычно одновременно запрашиваются HTML-документ, таблицы стилей, JavaScript, изображения и другие ресурсы, которых иногда бывает несколько десятков.

  • nodelay - меняет поведение при превышении лимита. Если он указан, то лишние запросы отклоняются сразу, а без него Nginx попытается ненадолго поставить их в очередь и обработать позже, если это позволит заданная скорость.

 

 

 

 

Какие значения выбирать

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

Например, ограничение 2r/s выглядит безопасным, но в действительности часто оказывается слишком жестким, ведь даже без какой-либо атаки пользователь может быстро обновить страницу, открыть несколько вкладок или выполнить несколько действий подряд в веб-интерфейсе. А в результате часть запросов получит ответ 429 Too Many Requests, хотя никакой вредоносной активности не происходило.

Для большинства проектов можно ориентироваться на такие значения:

  • корпоративный сайт - 5-10 запросов в секунду;
  • интернет-магазин - 10-20 запросов в секунду;
  • REST API - обычно 20–50 запросов в секунду, если операции не слишком ресурсоёмкие;
  • административная панель - 2-5 запросов в секунду с небольшим значением burst.

 

ВАЖНО! Эти цифры нельзя считать универсальными, но они помогают выбрать первую конфигурацию. А дальше уже стоит посмотреть на реальные журналы Nginx, характер нагрузки и поведение пользователей, после чего принять решение на изменение лимитов в ту или иную сторону. Иногда после нескольких дней наблюдений становится понятно, что лимит можно поднять, а бывает и наоборот.

 

 

 

 

Защита страницы авторизации

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

Пример настройки для такой страницы может выглядеть как-то так:

location = /login {
    limit_req zone=login_limit burst=5 nodelay;
}

 

С таким правилом один IP-адрес уже не сможет без пауз отправлять огромное количество попыток авторизации. Часть запросов будет сразу получать отказ, а приложение не станет каждый раз проверять логин и пароль через базу данных.

В таком случае нагрузка падает заметно. Заодно brute force становится менее удобным для атакующего, ведь скорость перебора уменьшается до неприемлемой, а подозрительные запросы проще увидеть в логах веб-сервера.

 

 

 

 

Чего rate limiting не умеет

Но как и у любого другого механизма, у rate limiting есть свои ограничения. Он достаточно хорошо справляется с простыми сценариями, но вот против некоторых типов атак его возможностей уже становится недостаточно.

Например, если запросы идут одновременно с десятков тысяч IP-адресов, а каждый источник укладывается в установленный лимит, то Nginx не увидит в этом ничего необычного. Для противодействия распределённым DDoS-атакам такого масштаба обычно используют CDN, системы очистки трафика или специализированные Anti-DDoS-сервисы.

Кстати, есть и ещё один важный момент. Rate limiting следит только за частотой обращений, а содержимое HTTP-запросов он не анализирует вовсе, поэтому обнаружить сложные атаки на уровне приложения, такие как попытки эксплуатации уязвимостей или вредоносные последовательности запросов, этот механизм не сможет.

Поэтому rate limiting лучше рассматривать как один из защитных рубежей, который сам по себе не решит все проблемы, но в сочетании с другими средствами безопасности заметно снижает риски и помогает серверу пережить многие простые атаки без серьёзных последствий.

 

 

 

Полезные рекомендации

Эффективность rate limiting во многом зависит от того, насколько аккуратно подобраны настройки. Универсальных значений, как мы уже упомянули выше, тут нет, зато есть несколько практических правил, которые помогают избежать типичных ошибок.

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

После изменения конфигурации стоит несколько дней понаблюдать за логами Nginx. Если код ответа 429 Too Many Requests начинает регулярно появляться у обычных пользователей (такое иногда случается после слишком агрессивных настроек), тогда лимиты лучше пересмотреть.

И ещё один важный момент. Rate limiting хорошо работает вместе с другими средствами защиты. Такие инструменты как Файервол, Fail2Ban, WAF, корректно настроенные таймауты соединений - все они дополняет друг друга. В итоге сервер становится гораздо устойчивее к автоматическим атакам и всплескам нежелательного трафика.

 

 

 

 

Вывод

Настроить rate limiting в Nginx можно буквально за несколько минут. При этом эффект оказывается вполне ощутимым сразу, так как сервер начинает лучше справляться с простыми DDoS-атаками, массовым сканированием и навязчивыми ботами. А дополнительных ресурсов этот механизм почти не требует.

Для VPS такая настройка давно стала хорошей практикой. Она снижает вероятность того, что один источник сможет создать чрезмерную нагрузку на ваш сервер, чем помогает сохранить запас производительности в моменты резкого роста числа запросов.

Конечно, rate limiting не заменяет полноценную защиту от распределённых DDoS-атак. Но вместе с файерволом, Fail2Ban, WAF и другими средствами безопасности он создаёт дополнительный рубеж, который отсекает значительную часть нежелательного трафика ещё до того, как запросы попадут в приложение. А если лимиты подобраны правильно, обычные посетители работы этого механизма, скорее всего, даже не заметят.

3v-Hosting Team

Автор

3v-Hosting Team

Команда 3v-Hosting - это группа преданных своему делу инженеров и операторов, которые занимаются созданием и поддержкой основы наших сервисов. Каждый день мы погружаемся в мир виртуальных и выделенных серверов, занимаясь всем, от развертывания и мониторинга до устранения реальных проблем, возникающих в производственных средах. Большинство наших статей основано на практическом опыте, а не просто на теории. Мы делимся своими наблюдениями о проблемах, с которыми сталкиваемся: перебоях в производительности, ошибках в настройке, тонкостях сетевых решений и архитектурных выборах, влияющих на стабильность и надежность. Наша миссия проста - мы хотим делиться знаниями, которые позволят вам управлять своими проектами с меньшим количеством неожиданностей и гораздо большей предсказуемостью.