MAATRIX / Блог / Защита nginx от ботов, сканеров и паразитного трафика

Защита nginx от ботов, сканеров и паразитного трафика

Блог MAATRIX · 2026-07-07

Как только сайт появляется в сети, к нему начинают ломиться сканеры: ищут /wp-login.php, /.env, /admin, дырявые PHP-скрипты. Плюс агрессивные парсеры выжирают ресурсы. Nginx умеет отбивать это сам — rate limiting, фильтры по User-Agent и связка с fail2ban. Настроим оборону по слоям.

Слой 1: rate limiting

['Ограничиваем частоту запросов с одного IP. В http-секции /etc/nginx/nginx.conf объявляем зоны:', '
http {\n    limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;\n    limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;\n    limit_conn_zone $binary_remote_addr zone=conn:10m;\n}
', 'Применяем в server/location. Для обычных страниц мягкий лимит с burst, для форм логина — жёсткий:', '
location / {\n    limit_req zone=general burst=20 nodelay;\n    limit_conn conn 10;\n}\n\nlocation = /wp-login.php {\n    limit_req zone=login burst=3 nodelay;\n}
', 'burst — очередь всплеска, nodelay отдаёт их сразу, но сверх лимита возвращает 503. Перегрузить сервер уже не выйдет.', 'Ключевой момент — переменная $binary_remote_addr вместо $remote_addr: она хранит IP в бинарном виде и занимает меньше памяти зоны. Зона размером 10m вмещает около 160 тысяч уникальных адресов — этого хватит любому среднему сайту. Если сервер за реверс-прокси или CDN, используйте $http_x_forwarded_for, иначе все запросы придут с одного IP балансировщика и лимит сработает по всем сразу.']

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK и США. Оплата картой РФ и по СБП.

Арендовать VPS под защищённый сайт

Слой 2: блокировка сканеров по User-Agent и путям

['Большинство сканеров палятся по User-Agent или лезут по типовым путям. Режем их до обработки бэкендом:', '
map $http_user_agent $bad_bot {\n    default 0;\n    ~*(nikto|sqlmap|nmap|masscan|zgrab|nuclei) 1;\n    "" 1;\n}\n\nserver {\n    if ($bad_bot) { return 444; }\n\n    location ~* /\\.(env|git|htaccess|aws) { deny all; return 404; }\n    location ~* (wp-config|xmlrpc|phpmyadmin) { deny all; return 404; }\n}
', 'Код 444 — фирменный nginx: рвёт соединение без ответа, экономит трафик и не даёт боту сигнала. Пустой User-Agent тоже блокируем — легальные клиенты его почти всегда заполняют.', "Директиву map объявляют в http-секции, а проверку if ($bad_bot) — внутри server. Не увлекайтесь блокировкой по User-Agent: легитимные боты Google, Yandex и Bing тоже приходят с характерными строками, и их резать нельзя, иначе выпадете из поиска. Блокируйте только явные инструменты атак (sqlmap, nikto, nuclei) и оставляйте белый список для поисковиков. Проверить, кто именно к вам ходит, помогает разбор логов: awk '{print $12}' access.log | sort | uniq -c | sort -rn | head."]

Слой 3: fail2ban против упорных

['Rate limit отбивает всплеск, но упорный сканер долбит часами. fail2ban читает логи nginx и банит IP в фаерволе. Ставим и создаём фильтр:', '
apt update && apt install -y fail2ban\nnano /etc/fail2ban/filter.d/nginx-badbot.conf
', '
[Definition]\nfailregex = ^<HOST> .* "(GET|POST|HEAD) .*(wp-login|xmlrpc|\\.env|phpmyadmin).*" (403|404|444)\nignoreregex =
', 'Джейл в /etc/fail2ban/jail.local:', '
[nginx-badbot]\nenabled = true\nport    = http,https\nfilter  = nginx-badbot\nlogpath = /var/log/nginx/access.log\nmaxretry = 3\nfindtime = 300\nbantime = 86400
', '
systemctl restart fail2ban\nfail2ban-client status nginx-badbot
']

Слой 4: гео-фильтр и лимит размеров

['Если аудитория из конкретных стран, отсекаем остальные модулем geo или ngx_http_geoip2. Плюс режем очевидные атаки на переполнение:', '
client_max_body_size 10m;\nclient_body_timeout 10s;\nclient_header_timeout 10s;\nlarge_client_header_buffers 2 1k;
', 'Короткие таймауты убивают медленные атаки типа Slowloris, когда бот держит соединение открытым по байту в секунду.']

Проверка и роль хостинга

['Симулируем нагрузку и смотрим, что лимиты срабатывают:', "
ab -n 200 -c 20 https://ваш-домен/\ntail -f /var/log/nginx/access.log | grep ' 444 '
", 'Вся эта оборона эффективна ровно настолько, насколько быстр диск и CPU: fail2ban парсит логи, nginx считает лимиты в памяти. На VPS MAATRIX с AMD EPYC + NVMe от $8/мес логи пишутся и читаются мгновенно, а root-доступ даёт полную свободу настроить фаервол и модули. Локации UK и США, оплата картой РФ, СБП, криптой или токеном MAAT — зарубежный сервер, доступный из России.']

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK и США. Оплата картой РФ и по СБП.

Арендовать VPS под защищённый сайт

Частые вопросы

Rate limit не отрежет реальных пользователей?

При правильном burst — нет. Начните с rate=10r/s и burst=20, смотрите логи на 503 и корректируйте под свой трафик.

Чем 444 лучше 403?

444 закрывает соединение без ответа: боту не за что зацепиться, а вы экономите трафик и CPU. 403 всё же генерирует HTTP-ответ.

Нужен ли Cloudflare, если есть эти правила?

Для мелких и средних проектов nginx + fail2ban закрывают почти всё. CDN нужен против крупных DDoS, но базовую гигиену он не заменяет.