Назад | Перейти на главную страницу

Nginx - можно ли безопасно использовать «если» на уровне серверного блока?

Документы 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.