Защита от ботов в Nginx: пошаговая настройка с нуля
За 20–30 минут вы настроите в Nginx базовую защиту от массовых запросов: ограничение частоты, одновременных соединений и блокировку явно вредных User-Agent. Конфигурация рассчитана на Nginx 1.25–1.27.

За 20–30 минут вы настроите в Nginx базовую защиту от массовых запросов: ограничение частоты, одновременных соединений и блокировку явно вредных User-Agent. Конфигурация рассчитана на Nginx 1.25–1.27 и не требует CAPTCHA, стороннего сервиса или изменений в приложении.
Что получится и где границы защиты
Nginx будет отсекать часть автоматического трафика до передачи запроса в PHP, Node.js или другой backend. Это снизит нагрузку на приложение и базу данных, но не превратит сайт в систему распознавания людей.
Настройка защищает от простых сценариев: частого сканирования, перебора URL, слишком большого числа соединений с одного IP и запросов от известных инструментов. Распределённая атака с тысячами адресов, корректными браузерными заголовками или украденными сессиями требует дополнительных мер.
Лимит запросов — это предохранитель для приложения, а не доказательство того, что перед вами бот.
Что нужно иметь до начала
- сервер с Nginx 1.25–1.27 и правами администратора;
- доступ к конфигурации Nginx, обычно к каталогу
/etc/nginx; - домен, который уже обслуживает этот Nginx;
- список адресов мониторинга, офисов или внутренних сервисов, которые нельзя ограничивать;
- возможность проверить сайт после перезагрузки конфигурации.
Если сайт работает за CDN, балансировщиком или обратным прокси, сначала выясните, какой IP Nginx видит в переменной $remote_addr. Без корректной настройки real IP несколько тысяч посетителей могут выглядеть для Nginx как один адрес.
Сноска. User-Agent — HTTP-заголовок, которым клиент сообщает тип программы. Его легко подделать, поэтому использовать его как единственный признак бота нельзя.
Шаг 1. Проверьте исходную конфигурацию
Сделайте резервную копию и проверьте синтаксис до изменений. Путь к основному файлу может отличаться на вашей системе.
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
sudo nginx -t
Проверка успешна, если в выводе есть строки syntax is ok и test is successful. Если уже есть ошибка, сначала исправьте её: новая защита не должна маскировать старую проблему.
Шаг 2. Создайте зоны ограничения
Директивы limit_req_zone и limit_conn_zone разрешены только в контексте http. Добавьте их внутрь блока http { ... } в /etc/nginx/nginx.conf. Не вставляйте этот фрагмент внутрь server.
http {
limit_req_zone $binary_remote_addr zone=site_rate:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=client_conn:10m;
# Остальные настройки http остаются здесь
}
Зона site_rate хранит состояние запросов по IP, а client_conn — число одновременных соединений. Значение 10m — размер общей памяти под эти записи, а не лимит трафика.
После сохранения снова выполните sudo nginx -t. Успешная проверка означает, что Nginx принял синтаксис и видит обе зоны.
Шаг 3. Добавьте правила для явно вредных клиентов
Создайте файл, который подключается внутри http. Например, /etc/nginx/conf.d/bot-protection.conf. В типовой установке Nginx файлы из conf.d уже подключаются строкой include /etc/nginx/conf.d/*.conf;; проверьте это в основном конфиге.
map $http_user_agent $blocked_bot {
default 0;
~*"(sqlmap|nikto|masscan|zgrab|nmap)" 1;
}
map $http_user_agent $empty_user_agent {
default 0;
"" 1;
}
map $request_uri $is_sensitive_path {
default 0;
~*"^/(wp-login\.php|xmlrpc\.php|\.env|phpmyadmin)" 1;
}
Регулярные выражения здесь ловят только очевидные сигналы. Пустой User-Agent не всегда означает атаку: его используют мониторинги, мобильные клиенты и внутренние интеграции. Поэтому не блокируйте такие запросы без проверки логов.
Проверьте конфигурацию командой sudo nginx -t. Ошибка "map directive is not allowed here" означает, что блок оказался не внутри http.
Шаг 4. Примените защиту к виртуальному хосту
Откройте конфигурацию нужного домена и добавьте директивы внутрь его блока server. Пример рассчитан на публичный сайт, а не на API с отдельной схемой авторизации.
server {
server_name example.com www.example.com;
if ($blocked_bot) {
return 403;
}
if ($is_sensitive_path) {
return 404;
}
limit_req zone=site_rate burst=20 nodelay;
limit_req_status 429;
limit_conn client_conn 30;
limit_conn_status 429;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
}
Замените example.com и сохраните собственную схему маршрутизации. Если у вас не WordPress и нет index.php, не копируйте строку try_files из примера.
Параметр rate=10r/s разрешает в среднем десять запросов в секунду на IP. burst=20 позволяет короткий всплеск. С nodelay запросы из этого запаса проходят сразу, но после исчерпания лимита Nginx отвечает кодом 429.
Если заданные значения слишком строгие для вашей аудитории, сайт начнёт ограничивать пользователей из офисов, университетов и мобильных сетей: десятки людей могут иметь один внешний IP.
Шаг 5. Добавьте исключения для доверенных адресов
Не добавляйте в белый список весь диапазон провайдера или облака «на всякий случай». Укажите только адреса, которыми вы управляете, и документируйте причину.
geo $trusted_client {
default 0;
203.0.113.10 1;
198.51.100.24 1;
}
map "$trusted_client:$blocked_bot" $deny_request {
default 0;
"0:1" 1;
}
server {
server_name example.com;
if ($deny_request) {
return 403;
}
limit_req zone=site_rate burst=20 nodelay;
limit_req_status 429;
}
Адреса из примера зарезервированы для документации. Замените их на реальные IP или удалите блок. Проверка пройдена, если запрос с доверенного адреса не получает 403 из-за совпадения User-Agent.
Шаг 6. Проверьте ответ и включите конфигурацию
Сначала проверьте, что Nginx принимает финальную конфигурацию, затем перезагрузите его без остановки рабочих соединений.
sudo nginx -t
sudo systemctl reload nginx
curl -I https://example.com/
В обычном ответе вы увидите статус сайта, например 200 или 301. Для теста ограничения отправьте много запросов из контролируемой среды, а не с домашнего IP во время работы сайта.
for request_number in $(seq 1 60); do
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/
done
После превышения лимита среди ответов должны появиться 429. Если все ответы остаются 200, проверьте, что запросы попадают в нужный server, а директива limit_req не находится в другом виртуальном хосте.
Если не получилось
Сайт отдаёт 500 или Nginx не перезагружается
Выполните sudo nginx -t. Сообщение "unknown directive" обычно указывает на опечатку или модуль, которого нет в вашей сборке. Не перезапускайте сервис, пока тест не завершится успешно.
Вместо сайта появляется 403
Проверьте строки с if, регулярные выражения и фактический User-Agent. Логи обычно находятся в /var/log/nginx/access.log и /var/log/nginx/error.log. Сначала временно уберите правило блокировки, затем добавляйте выражения по одному.
Все посетители получают 429
Проверьте, не стоит ли Nginx за прокси, который передаёт один адрес для всех клиентов. Также увеличьте лимит постепенно и учитывайте страницы, которые загружают десятки ресурсов параллельно.
Мониторинг перестал видеть сайт
Добавьте его исходный IP в исключения только после проверки адреса в документации сервиса мониторинга. Если IP динамический, фиксированное исключение быстро устареет.
Защита не останавливает распределённый сканер
Это ожидаемое ограничение. Лимит на один IP не заменяет CDN, WAF, авторизацию для служебных маршрутов и защиту от перебора учётных записей.
Что настроить дальше
В течение суток после включения соберите статистику по кодам 403 и 429, адресам клиентов, URL и User-Agent. Смотрите не только количество блокировок, но и долю ошибочных ограничений: если реальные пользователи получают 429, снижайте агрессивность правила, а не добавляйте исключения без проверки.
Следующим шагом разделите лимиты по типам запросов. Для страницы входа, поиска и API обычно нужны разные значения. Отдельно настройте корректную передачу реального IP через доверенный прокси и только затем усиливайте правила.
Карточки для маркетплейсов: Таблица товаров и папка фотографий на входе — комплект слайдов и описаний на выходе, по требованиям Wildberries и Ozon.
Спросить за 5 ₽Источники: NGINX documentation: Limiting Access to Proxied HTTP Resources, NGINX documentation: ngx_http_limit_req_module
Частые вопросы
Можно ли защитить сайт от всех ботов только средствами Nginx?
Почему нельзя просто заблокировать пустой User-Agent?
Что означает ответ 429?
Могут ли обычные посетители получить 429?
Что делать, если Nginx видит IP прокси, а не посетителя?
Нужно ли добавлять правила в robots.txt?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.