Защита nginx от ботов, сканеров и паразитного трафика
Как только сайт появляется в сети, к нему начинают ломиться сканеры: ищут /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, но базовую гигиену он не заменяет.