Страницы

Поиск по вопросам

понедельник, 8 июля 2019 г.

Nginx | Странное поведение location

Конфигурация сервера:
server { listen 80; server_name example.com;
root /home/Web/www/$server_name/; index index.php index.html;
charset utf-8;
location ~* \.php$ { return 403; }
location / { } }
Индексный файл - index.php. При загрузке example.com/ Nginx отдает именно его (т.к. указано index index.php index.html;), срабатывает location ~* \.php$ и выдает 403 ошибку, все ОК, как и должно.
Но если я внесу такое изменение в блок:
location / { proxy_pass http://backend; }
То при загрузке example.com/ будет сразу проксировать на Backend, хотя index стоит, и обрабатываемый его location тоже.
Я не понимаю, почему если блок location / пустой, то будет обрабатываться подходящий location ~* \.php$, если же поставить проксирование, то запрос начинает обрабатывать location /
Почему так? Не срабатывает настройка index index.php index.html; или что? Как это починить? Спасибо.


Ответ

Вообще ваш пример разобран в документации на nginx
Обработка запроса “/” более сложная. Ему соответствует только префиксный location “/”, поэтому запрос обрабатывается в нём. Затем директива index проверяет существование индексных файлов согласно своих параметров
Кроме этого, весьма рекомендую многократно, до полного просветления перечитывать раздел "порядок применения location" (например раз и два).
Конкретно ваш пример разобранный до самой мелочи.
Как разбирается URI / в вашем конфиге:
А) для случая пустого location /
Для запроса / подходит только один location -- location /. Этот location пустой, но наследует root и index от блока server. Применяется внутреннее перенаправление (директива index) c / на /index.php. Начинается обработка НОВОГО запроса. Для запроса /index.php подходят как location ~* \.php$, так и location \, будет использоваться (см. порядок приоритетов location) location заданный регуляркой, он отдаст 403 и закончит обработку запроса.
Для наглядности эквивалентный конфиг сервера:
server { listen 80; server_name example.com;
root /home/Web/www/$server_name/;
charset utf-8;
location ~* \.php$ { return 403; }
location / { index index.php index.html; } }
Так наглядно видно, что ваш пример полностью соответствует разобранному в документации.
Б) для случая location с прокси-сервером
Для запроса / подходит только один location -- location /. Этот location передаёт обработку бекенду, на этом обработка запроса nginx'ом закончена.
Это что касается запроса, заданного в самом вопросе. В комментариях был ещё один запрос:
Если ввести example.com/index.php, то location ~* .php$ {} срабатывает, в независимости, есть ли что-то в блоке location /{} или нет.
Для запроса /index.php подходит какой location? Правильно -- оба, но первым будет применяться location ~* .php$ (см. приоритет location), а в нём у вас обработка заканчивается выдачей 403.
Как это починить?
Выше я описывал то, как работает ваш конфиг. С вашей точки зрения он работает "неправильно". А вот как правильно -- вы не пишете, поэтому тут нужно, чтобы вы чётко поставили задачу -- что вы, собственно, хотите от nginx? Я полностью согласен с тем комментарием Что «и подобное»? -- это неконкретно и непонятно.
Подозреваю, что вам нужно location = / {...} но не уверен. Возможно, стоит задать новый вопрос, в котором сослаться на текущий и чётко пояснить, какие вы хотите видеть location и что куда хотите отправлять. И лучше не пытайтесь "для примера" заменять одно действие другим: хотите отдать файл -- так и пишите, а не "отдать файл, но вместо этого для примера 403". Это только запутывает и вас как спрашивающего и отвечающих.

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

Отправить комментарий