Документы Nginx недвусмысленно предупреждают, что если зло и их следует по возможности избегать, и похожие предупреждения разбросаны по всему Интернету.
Однако большинство этих предупреждений сосредоточены именно на том, насколько сильно if
ведет себя в location
блоки. Кроме того, в документации Nginx говорится, что:
Единственные 100% безопасные вещи, которые можно сделать внутри, если в контексте местоположения:
возвращение ...;
переписать ... последний;
Мой вопрос: безопасно ли использовать if
на уровне server
блок (а не location
block), если единственная содержащаяся в нем директива - это return
? Например, следующее перенаправление с www на не www:
server {
listen 80;
server_name example.com www.example.com;
if ($http_host != example.com) {
return 301 http://example.com$request_uri;
}
# more config
}
Вторичный вопрос: я знаю, что рекомендуемый метод для этого - с двумя server
блоки, которые имеют разные значения для server_name
. Если это является приемлемое использование для if
, есть ли причина по-прежнему использовать два отдельных server
блоки?
Из «Если зло»:
В некоторых случаях также возможно переместить if на уровень сервера (где это безопасно, поскольку в нем разрешены только другие директивы модуля перезаписи).
Это говорит о том, что if
в server
блок безопаснее (r), чем в location
блок.
Одним из первых шагов, когда nginx получает запрос, является оценка HTTP. Host
заголовок / поле TLS SNI и выбор виртуального хоста на основе результата этой оценки.
Это означает, что Host
заголовок всегда обрабатывается.
Теперь, если вы укажете if
заявление для перенаправления, это означает, что Host
заголовок будет проверен дважды, сначала для выбора виртуального хоста, а затем для проверки if
состояние. Это вдвое больше работы процессора.
Контр-аргументом может быть потребление памяти отдельным серверным блоком. Однако распределение памяти такое же на протяжении всего времени жизни процесса nginx, в то время как двойная оценка Host
заголовок происходит при каждом запросе.
Вы жестяная банка сделайте это, но это крайне не рекомендуется. Уже есть официальный объяснение по этому поводу.
Чтобы запустить несколько сайтов, я бы рекомендовал создать несколько файлов конфигурации для каждого сайта, а затем включить местоположение в основной nginx.conf.