Нельзя остановить вредоносных ботов. Давайте просто отсекаем их на уровне nginx – как убрать подозрительные URL в конфиге blackhole.conf
Очистка подозрительных URL через nginx blackhole.conf
Когда веб‑приложение становится доступным в интернете, независимо от выбранного фреймворка, подозрительные запросы начинают поступать.
- Не существующий
/wp-admin/ /index.php,/xmlrpc.php– даже если PHP не используется.git,.env,/cgi-bin/– чувствительные файлы и каталогиwso.php,shell.php,test.php…
Это не ваш собственный сервис, а мировые сканеры и боты, которые пытаются найти уязвимости. Честно говоря, сервер, который не сталкивается с этим, почти не существует.
Если защита реализована на уровне приложения, большинство запросов обрабатывается как 400/404. Но проблема появляется после этого:
- Логи загрязняются – до того, как реальные пользователи сделают запрос, половина лога уже заполнена подозрительными запросами.
- Небольшая нагрузка на CPU – даже «безопасные» запросы требуют лишних вычислений.
- Усталость админа – каждый раз, открывая логи, видишь сотни строк
/wp-login.php.
Поэтому я предпочитаю отсеивать такие запросы на уровне nginx, до того, как они дойдут до приложения. Это как отправить их в «черную дыру» на уровне хоста.
В этой статье:
- Почему «первичная блокировка на уровне nginx» полезна
- Как управлять общими правилами через файл
blackhole.conf - Примеры реальных конфигураций nginx
1. Почему блокировка только в приложении недостаточна
Обычный подход:
- URL, которого нет в роутере/контроллере → 404
- Исключения → 400/500
- Логи → APM / лог‑коллектор
Функционально всё ок, но с точки зрения эксплуатации есть проблемы:
- Шум в логах – процент ошибок/404 растёт из‑за сканеров, а не реальных пользователей.
- Блокировка слишком глубоко – запрос уже прошёл через фреймворк, мидлвари и роутинг.
- Накопительная нагрузка – сканеры приходят постоянно, и их количество может быть значительным.
Поэтому я стараюсь отсеивать «неполезные» запросы как можно выше, в nginx.
2. Создание «черной дыры» в nginx: мгновенное отключение через 444
В nginx есть собственный статус‑код, которого нет в HTTP‑стандарте:
return 444;
- Не отправляется заголовок, не отправляется тело
- Просто закрывается TCP‑соединение
С его помощью можно полностью отключить запросы, которые выглядят 100 % подозрительными.
Преимущества:
- Запрос не доходит до приложения (CPU‑нагрузка нулевая)
- Логи можно полностью отключить для таких запросов
- Логи приложения остаются чистыми
3. Управление правилами через один файл blackhole.conf
Вместо того чтобы прописывать правила в каждом сервер‑блоке, удобно хранить их в одном файле, например /etc/nginx/blackhole.conf:
# /etc/nginx/blackhole.conf
# 1. Скрытые и конфиденциальные каталоги (.git, .env, IDE и т.д.)
location ~* (^|/)\.(git|hg|svn|bzr|DS_Store|idea|vscode)(/|$) { return 444; }
location ~* (^|/)\.env(\.|$) { return 444; }
location ~* (^|/)\.(?:bash_history|ssh|aws|npm|yarn)(/|$) { return 444; }
# 2. Неиспользуемые CMS‑админки / уязвимости
location ^~ /administrator/ { return 444; }
location ^~ /phpmyadmin/ { return 444; }
# 3. PHP/CGI/WordPress‑следы
# Рекомендуется для стеков без PHP (Node, Go, Python)
location ~* \.(?:php\d*|phtml|phps|phar)(/|$) { return 444; }
location ^~ /cgi-bin/ { return 444; }
location ~* ^/(wp-admin|wp-includes|wp-content)(/|$) { return 444; }
# 4. Часто сканируемые файлы/пути
location ~* ^/(?:info|phpinfo|test|wso|shell|gecko|moon|root|manager|system_log)\.php(?:/|$)? {
return 444;
}
location ~* ^/(?:autoload_classmap|composer\.(?:json|lock)|package\.json|yarn\.lock|vendor)(?:/|$) {
return 444;
}
location ~* ^/(?:_profiler|xmrlpc|xmlrpc|phpversion)\.php(?:/|$)? {
return 444;
}
# 5. Бэкапы/временные/дампы
location ~* \.(?:bak|backup|old|orig|save|swp|swo|tmp|sql(?:\.gz)?|tgz|zip|rar)$ {
return 444;
}
# 6. well‑known: разрешаем только ACME, остальные закрываем
location ^~ /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
location ^~ /.well-known/ {
return 444;
}
# 7. Защита методов (опционально)
if ($request_method !~ ^(GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS)$) {
return 405;
}
В каждом сервер‑блоке добавляем только одну строку:
http {
server {
listen 80;
server_name example.com;
include /etc/nginx/blackhole.conf;
# остальные правила маршрутизации...
}
}
Теперь большинство «неиспользуемых» путей блокируются до того, как запрос достигнет приложения.
4. Уменьшение шума в логах (опционально)
Если хотите, чтобы запросы, попадающие в черную дыру, вообще не записывались в access_log, можно использовать map:
http {
map $request_uri $drop_noise_log {
default 0;
~*^/(?:\.git|\.env) 1;
~*^/(wp-admin|wp-includes|cgi-bin) 1;
~*\.php(?:/|$) 1;
}
server {
listen 80;
server_name example.com;
include /etc/nginx/blackhole.conf;
access_log /var/log/nginx/access.log combined if=$drop_noise_log;
}
}
$drop_noise_log= 1 – запрос не логируется$drop_noise_log= 0 – обычный лог
В продакшене сначала включайте логирование, проверяйте, что «правильные» пользователи не попадают в список, а затем переключайте на if=$drop_noise_log.
5. Как избежать ложных срабатываний
Главное правило: не быть слишком агрессивным.
- Подбирайте правила под стек – если проект не использует PHP, блокируйте
.phpполностью. Если у вас Laravel, исключите эти правила. - Начинайте с 404/403 – сначала возвращайте 403, наблюдайте, не мешают ли они реальным пользователям, а потом переходите к 444.
- Блокируйте критичные пути –
.git,.env, бэкапы,phpinfo.phpможно закрыть без опасений. - Понимайте приоритеты – в nginx
locationимеет порядок: точное совпадение, префикс, регулярное выражение. Не ставьте правила выше, чем основной роутер.
6. Где каждая часть отвечает за безопасность
- nginx blackhole – отсекает «пустые» запросы на раннем этапе.
- Приложение – проверяет бизнес‑логику, права доступа, валидность входных данных.
- WAF/другие решения – паттерн‑базированные атаки, DDoS, продвинутый бот‑фильтр.
Каждый слой дополняет остальные, а не заменяет.
Итоги
Если ваш сервис доступен в интернете, полностью избавиться от «подозрительных» запросов невозможно. Но можно изменить подход:
«Если они придут, просто отсекаем их в nginx, не давая дойти до приложения».
С помощью blackhole.conf и ответа 444 вы:
- Чистите логи приложения
- Уменьшаете нагрузку на сервер
- Делаете мониторинг и анализ более удобными
В итоге, когда вы открываете логи в 2 : 00, вместо бесконечной строки /wp-login.php вы видите только реальные запросы – это уже приятный бонус.
Если у вас уже есть nginx, попробуйте добавить свой blackhole.conf. Через несколько дней вы поймёте, почему это было необходимо.

Комментариев нет.