Настройка Nginx для защиты от уязвимостей и атак

2025-12-26 17:59:31 Время чтения 11 мин 35

Кошмар каждого системного администратора: сервер парализован, логи заполнены ошибками, кто-то атакует внутреннюю инфраструктуру и выполняет действия от имени пользователя.

Обычно это происходит из-за таких уязвимостей, как RCE (удаленное исполнение кода), SSRF (подделка запросов на стороне сервера) и CSRF (межсайтовая подделка запроса).

И такие атаки — не редкость.

Кошмар каждого системного администратора: сервер парализован, логи заполнены ошибками, кто-то атакует внутреннюю инфраструктуру и выполняет действия от имени пользователя.

Обычно это происходит из-за таких уязвимостей, как RCE (удаленное исполнение кода), SSRF (подделка запросов на стороне сервера) и CSRF (межсайтовая подделка запроса).

И такие атаки — не редкость.

По данным центра исследования киберугроз Solar 4RAYS, во втором квартале 2025 года число обнаруженных уязвимостей в популярных веб-приложениях выросло на 58% по сравнению с предыдущим кварталом, а решения «Лаборатории Касперского» ежедневно обнаруживают 500 тыс. новых вредоносных файлов.

Чтобы избежать атак или как минимум сократить последствия, важно грамотно настроить сервер.

В этой статье разбираем, как можно снизить угрозу уязвимостей и атак на Nginx — самый популярный веб-сервер в мире.

Итак, вот наш топ рекомендаций для защиты Nginx.

Проверьте файлы, доступные публично

При типовой конфигурации для работы с PHP конфигурация выглядит так:

Директива try_files выполняется слева направо, то есть при запросе сначала проверяется доступность файла из запроса — и, при его наличии, он будет отдан. Это базовый функционал веб-сервера, но таким образом можно извне прочитать различные файлы конфигурации в папке приложения, файлы версий Composer, .bak, .sql и т. д., о которых разработчик не задумывается.

При использовании Composer, кроме доступа к файлам версий, при неверной конфигурации существует возможность запуска PHP-файлов зависимостей из папки «vendor» напрямую. Иногда зависимости содержат файлы примеров, скриптов или различных модулей, не задействованных в основном приложении, с помощью которых возможно исполнение кода или отображение произвольного текста, открывающее возможность для проведения CSRF-атак.Внимательно относитесь к файлам, которые становятся доступны публично, — храните приватные данные вне web-root, отключайте листинг директорий и явно ограничивайте доступ к чувствительным типам файлов через deny all или точные правила try_files.

Переменные в proxy_pass

proxy_pass используется для перенаправления запросов с веб-сервера на другой сервер и указывает на путь или URL, на который проксируется запрос, полученный Nginx.

Рассмотрим такую конфигурацию:

Мы рекомендуем быть аккуратными с использованием переменных в proxy_pass, поскольку если на их содержимое может влиять злоумышленник (например, как в примере выше, когда содержимое $http_host и $request_uri берется из HTTP-запроса), это дает возможность организовать атаку типа SSRF — отправлять запросы внутренним сервисам.

Грамотным решением может стать исключение использования непроверенных переменных в proxy_pass. Если есть возможность, вместо подстановки $http_host задавайте фиксированный целевой адрес или применяйте строгую валидацию и маппинг допустимых хостов.

Будьте осторожны со слешами

При лишних слешах можно вставить «..» — и получить доступ туда, куда разработчик приложения не предполагал предоставлять доступ.

При такой конфигурации:

Если мы выполним запрос:

Сервер Nginx достаточно прямолинейно обработает запрос и добавит ‘../settings.py’ к значению директивы alias:

Таким образом можно получить доступ за пределы ожидаемой разработчиком папки.

Так же это работает и с другими директивами, такими как proxy_pass:

Так можно выйти за пределы ожидаемого сегмента адреса (v1 в нашем случае). Например, если в качестве проксируемого сервера используется Apache, то данным запросом можно раскрыть его статусную страницу.

Apache получит запрос: http://apiserver/v1/../server-status

Старайтесь использовать root вместо alias, если структура приложения позволяет, и валидируйте пути на стороне проксируемого сервера.

Будьте аккуратны с FastCGI

Когда Nginx передает запросы с помощью протокола FastCGI, каждое сообщение FastCGI содержит набор переменных среды. Поэтому настройка Nginx должна включать проверку, какие переменные среды передаются через директивы fastcgi_param, — чтобы избежать исполнения кода или раскрытия данных, не предусмотренных разработчиком.

Например, безобидная конфигурация:

Для URL, оканчивающихся на .php, Nginx не будет проверять существование файла и слепо передаст в переменной SCRIPT_FILENAME нормализованный путь из запроса. В зависимости от типа и версии вашего FastCGI-бэкенда, типа операционной системы, используемой локали, файловой системы, а также конфигурации самого Nginx, существуют различные способы манипуляций с адресом для исполнения кода, не предусмотренного разработчиком.

Переменная SCRIPT_FILENAME будет доступна в PHP $_SERVER[’SCRIPT_NAME’]. Если она или ее производные выводятся на страницу без экранирования, то злоумышленник может вставить в адресную строку вредоносный код, который отобразится на странице в оригинальном виде.

Так же, например, можно вставить пробел, слеш, null-символ или другие спецсимволы в адрес, чтобы FastCGI-бэкенд исполнил не тот файл, который указан в адресе.

Классический пример:

Nginx передаст этот запрос FastCGI-бэкенду, а код из avatar.jpg может быть исполнен как скрипт (или, в зависимости от бэкенда, отдан как текст).

В современном PHP-FPM директива security.limit_extensions содержит список допустимых расширений файлов для исполнения и должна предотвратить конкретно этот сценарий, но нужно быть аккуратными с другими FastCGI-бэкендами, а также при более пермиссивной настройке security.limit_extensions (например, часто туда добавляют .inc).

Чтобы не передавать лишние запросы, можно проверять наличие файлов в самом Nginx:

Будьте осторожны с переменными

$uri и $document_uri — это нормализованные переменные, то есть последовательность вида %0d%0a декодируется в реальные символы переноса строки (CRLF).

Таким образом в подобной конфигурации можно вставить неожиданный перенос строки и дописать свои заголовки:

Nginx вернет:

Для защиты от подобных CSRF в Nginx важно тщательно управлять заголовками, которые могут быть применены злоумышленниками, использовать безопасные переменные вроде $request_uri, а также merge_slashes on — чтобы исключить обход правил через манипуляции с URL.

Конфигурация SSL должна быть надежной

Мы рекомендуем не играть в криптографа и использовать надежные средства для конфигурации SSL — например, Mozilla SSL Configuration Generator.

Так можно предотвратить MITM-атаки, при которых злоумышленник перехватывает и потенциально изменяет коммуникацию между сторонами, что позволяет ему просматривать содержимое всех передаваемых ими сообщений, удалять и изменять их.

Заключение

Любые атаки — серьезная угроза для сайтов и приложений, а защита от них требует комплексного подхода. В этой статье мы разобрали неочевидные нюансы, которые стоит учесть при настройке Nginx, при этом для защиты VPS-сервера могут быть полезны и другие способы.

Например, если ваша инфраструктура находится в облаке, можно использовать CDN — сеть доставки контента, которая обеспечит дополнительную защиту от атак благодаря переводу запросов к контенту на серверы CDN.

Если у вас возникли вопросы, свяжитесь с нами удобным для вас способом — и мы обязательно ответим. Также ждем вас в нашем официальном Telegram-канале, а пообщаться на любую тему с коллегами по цеху и сотрудниками Beget вы можете в нашем чате.

Категории: PR