Защита Nginx: блокировка SQL-инъекций, файловых инъекций и вредоносных User-Agent
Кратко Кратко: В этой статье показано, как вставить набор правил в каждый vhost Nginx, чтобы блокировать распространённые SQL‑инъекции, файловые инъекции, спам и агентов, потребляющих трафик. Это стартовый набор — обязательно следите за логами и дополняйте правила под свою среду.
Измените свои vhosts Nginx
Правила, приведённые ниже, нужно вставить в каждый vhost (внутрь блока server {}) где вы хотите их использовать. К сожалению, их нельзя поместить глобально в блок http {}, потому что директива set там недоступна.
server {
[...]
## Block SQL injections
set $block_sql_injections 0;
if ($query_string ~ "union.*select.*\(") {
set $block_sql_injections 1;
}
if ($query_string ~ "union.*all.*select.*") {
set $block_sql_injections 1;
}
if ($query_string ~ "concat.*\(") {
set $block_sql_injections 1;
}
if ($block_sql_injections = 1) {
return 403;
}
## Block file injections
set $block_file_injections 0;
if ($query_string ~ "[a-zA-Z0-9_]=http://") {
set $block_file_injections 1;
}
if ($query_string ~ "[a-zA-Z0-9_]=(\.\.?//?)+") {
set $block_file_injections 1;
}
if ($query_string ~ "[a-zA-Z0-9_]=/([a-z0-9_.]//?)+") {
set $block_file_injections 1;
}
if ($block_file_injections = 1) {
return 403;
}
## Block common exploits
set $block_common_exploits 0;
if ($query_string ~ "(<|%3C).*script.*(>|%3E)") {
set $block_common_exploits 1;
}
if ($query_string ~ "GLOBALS(=|\[|%[0-9A-Z]{0,2})") {
set $block_common_exploits 1;
}
if ($query_string ~ "_REQUEST(=|\[|%[0-9A-Z]{0,2})") {
set $block_common_exploits 1;
}
if ($query_string ~ "proc/self/environ") {
set $block_common_exploits 1;
}
if ($query_string ~ "mosConfig_[a-zA-Z_]{1,21}(=|%3D)") {
set $block_common_exploits 1;
}
if ($query_string ~ "base64_(en|de)code\(.*\)") {
set $block_common_exploits 1;
}
if ($block_common_exploits = 1) {
return 403;
}
## Block spam
set $block_spam 0;
if ($query_string ~ "\b(ultram|unicauca|valium|viagra|vicodin|xanax|ypxaieo)\b") {
set $block_spam 1;
}
if ($query_string ~ "\b(erections|hoodia|huronriveracres|impotence|levitra|libido)\b") {
set $block_spam 1;
}
if ($query_string ~ "\b(ambien|blue\\spill|cialis|cocaine|ejaculation|erectile)\b") {
set $block_spam 1;
}
if ($query_string ~ "\b(lipitor|phentermin|pro[sz]ac|sandyauer|tramadol|troyhamby)\b") {
set $block_spam 1;
}
if ($block_spam = 1) {
return 403;
}
## Block user agents
set $block_user_agents 0;
# Don't disable wget if you need it to run cron jobs!
#if ($http_user_agent ~ "Wget") {
# set $block_user_agents 1;
#}
# Disable Akeeba Remote Control 2.5 and earlier
if ($http_user_agent ~ "Indy Library") {
set $block_user_agents 1;
}
# Common bandwidth hoggers and hacking tools.
if ($http_user_agent ~ "libwww-perl") {
set $block_user_agents 1;
}
if ($http_user_agent ~ "GetRight") {
set $block_user_agents 1;
}
if ($http_user_agent ~ "GetWeb!") {
set $block_user_agents 1;
}
if ($http_user_agent ~ "Go!Zilla") {
set $block_user_agents 1;
}
if ($http_user_agent ~ "Download Demon") {
set $block_user_agents 1;
}
if ($http_user_agent ~ "Go-Ahead-Got-It") {
set $block_user_agents 1;
}
if ($http_user_agent ~ "TurnitinBot") {
set $block_user_agents 1;
}
if ($http_user_agent ~ "GrabNet") {
set $block_user_agents 1;
}
if ($block_user_agents = 1) {
return 403;
}
[...]
}Если одно из правил совпадает с запросом, клиенту возвращается ошибка 403 Forbidden. Правило с wget здесь закомментировано, потому что оно также заблокирует cron-задачи, которые используют wget — это часто встречается в современных CMS. Если ваше приложение не использует wget, можно раскомментировать это правило.
Не забудьте перезагрузить nginx:
service nginx reloadСерверы Nginx в ISPConfig
Эти правила также можно вставить в поле Nginx Directives в ISPConfig. Просто вставьте правила в соответствующее поле на вкладке опций сайта в ISPConfig, без окружающего блока server { … }. Перезагрузка nginx будет выполнена ISPConfig автоматически при сохранении изменений.
Когда это не сработает
- Правила основаны на регулярных выражениях для строк запроса (query_string). Они не отслеживают данные в теле POST-запроса или бинарные полезные нагрузки.
- Сложно учесть все варианты URL-кодирования и многоступенчатого обфускатора; некоторые полезные нагрузки могут пройти при многоуровневом кодировании.
- Есть риск ложных срабатываний для легитимных запросов: тщательно тестируйте сайт после включения правил.
Альтернативные подходы
- WAF на уровне приложения (например, ModSecurity) — более надёжный фильтр с правиловым набором и режимом обучения.
- CDN с встроенным WAF (Cloudflare, Fastly и т. п.) — снижает нагрузку и блокирует часть атак ещё на границе сети.
- Исправления в коде приложения: подготовленные выражения (prepared statements), валидация и нормализация входных данных.
- Блокировка IP и rate limiting (limit_req, fail2ban) для снижения шума и грубых попыток перебора.
Модель принятия решений
Дефенс-ин-дэпс (defense in depth): комбинируйте периметровую фильтрацию (на nginx), WAF/CDN и обязательную защиту на уровне приложения. Нельзя полагаться на один уровень защиты.
Чек-лист для ролей
- DevOps:
- Добавить правила в нужные vhost и перезагрузить nginx.
- Проверить, что нет синтаксических ошибок и что сайт отвечает.
- Настроить ротацию логов и мониторинг 403.
- Разработчик:
- Протестировать пользовательские формы и загрузки файлов.
- Убедиться, что валидные запросы не блокируются.
- Аналитик безопасности:
- Просмотреть логи на предмет ложных срабатываний и новых паттернов атак.
- Обновить набор правил по мере необходимости.
Критерии приёмки
- Правила применены в целевых vhost и nginx успешно перезагружен.
- Тестовые вредоносные строки (например, “union select” или попытки include через http://) возвращают 403.
- Легитимный функционал сайта продолжает работать без сбоев.
Тесты и кейсы
- Попытка: ?id=1 UNION SELECT -> ожидается 403.
- Попытка: ?file=http://evil.example/ -> ожидается 403.
- Попытка с User-Agent “GetRight” -> ожидается 403.
- Тесты регресса: формы поиска, загрузки файлов, ссылки с параметрами.
Факто-бокс
- Код ответа при срабатывании правил: 403 Forbidden.
- Правила применяются в рамках server {} (vhost).
- Директива set не разрешена в блоке http {} — поэтому набор нужно вставлять в каждый vhost.
Рекомендации по безопасности и эксплуатации
- Логи: включите подробный доступ и собирайте 403-ошибки в отдельный поток для анализа.
- Обновления: периодически пересматривайте список вредоносных User-Agent и словарь спама.
- Не полагайтесь только на фильтрацию URL; внедряйте валидацию и подготовленные запросы в приложении.
Ссылки
- nginx: http://nginx.org/
Об авторе
Falko Timme — владелец Timme Hosting (высокопроизводительный хостинг на nginx). Он является ведущим сопровождающим HowtoForge (с 2005) и одним из основных разработчиков ISPConfig (с 2000). Также он внес вклад в книгу O’Reilly “Linux System Administration”.
Подытожим
- Эти правила — практичный старт для фильтрации популярных атак на уровне vhost.
- Тестируйте и адаптируйте под свою инфраструктуру.
- Комбинируйте с WAF, CDN и защитой на уровне приложения.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone