Spec-Zone.ru › nginx

Имена серверов

  • Имена с подстановкой
  • Имена с использованием регулярных выражений
  • Разные имена
  • Международные имена
  • Выбор виртуального сервера
  • Оптимизация
  • Совместимость

Имена серверов определяются с помощью директивы server_name и определяют, какой блок server будет использован для данного запроса. Смотрите также «Как nginx обрабатывает запрос». Они могут быть определены с использованием точных имён, имён с подстановкой или регулярных выражений:

server {
    listen       80;
    server_name  example.org  www.example.org;
    ...
}

server {
    listen       80;
    server_name  *.example.org;
    ...
}

server {
    listen       80;
    server_name  mail.*;
    ...
}

server {
    listen       80;
    server_name  ~^(?<user>.+)\.example\.net$;
    ...
}

При поиске виртуального сервера по имени, если имя совпадает с более чем одной указанной вариантом, например, как с именем с подстановкой, так и с регулярным выражением, будет выбран первый соответствующий вариант в следующем порядке приоритетов:

  1. точное имя
  2. самое длинное имя с подстановкой, начинающееся со звёздочки, например, «*.example.org»
  3. самое длинное имя с подстановкой, заканчивающееся звёздочкой, например, «mail.*»
  4. первое соответствующее регулярное выражение (в порядке появления в файле конфигурации)

Имена с подстановкой

Имя с подстановкой может содержать звёздочку только в начале или конце имени и только на границе с точкой. Имена «www.*.example.org» и «w*.example.org» некорректны. Однако эти имена можно указать, используя регулярные выражения, например, «~^www\..+\.example\.org$» и «~^w.*\.example\.org$». Звёздочка может соответствовать нескольким частям имени. Имя «*.example.org» соответствует не только www.example.org, но и www.sub.example.org.

Специальное имя с подстановкой в формате «.example.org» может использоваться для соответствия как точному имени «example.org», так и имени с подстановкой «*.example.org».

Имена с использованием регулярных выражений

Регулярные выражения, используемые nginx, совместимы с регулярными выражениями языка программирования Perl (PCRE). Для использования регулярного выражения имя сервера должно начинаться с символа тильды:

server_name  ~^www\d+\.example\.net$;

в противном случае оно будет обрабатываться как точное имя или, если выражение содержит звёздочку, как имя с подстановкой (и скорее всего как некорректное). Не забудьте установить якоря «^» и «$». Они не требуются синтаксически, но логически. Также обратите внимание, что точки в доменных именах должны быть экранированы с помощью обратной косой черты. Регулярное выражение, содержащее символы «{» и «}», должно быть заключено в кавычки:

server_name  "~^(?<name>\w\d{1,3}+)\.example\.net$";

в противном случае nginx не сможет запуститься и выведет сообщение об ошибке:

directive "server_name" is not terminated by ";" in ...

Используя именованные группы захвата регулярных выражений, можно позже использовать их в качестве переменных:

server {
    server_name   ~^(www\.)?(?<domain>.+)$;

    location / {
        root   /sites/$domain;
    }
}

Библиотека PCRE поддерживает именованные группы захвата, используя следующий синтаксис:

?<name> Синтаксис, совместимый с Perl 5.10, поддерживается с PCRE-7.0
?'name' Синтаксис, совместимый с Perl 5.10, поддерживается с PCRE-7.0
?P<name> Синтаксис, совместимый с Python, поддерживается с PCRE-4.0
Если nginx не может запуститься и выводит сообщение об ошибке:
pcre_compile() failed: unrecognized character after (?< in ...

это означает, что библиотека PCRE устаревшая, и следует попробовать синтаксис «?P<name>». Группы захвата также можно использовать в цифровом формате:

server {
    server_name   ~^(www\.)?(.+)$;

    location / {
        root   /sites/$2;
    }
}

Однако такое использование следует ограничивать простыми случаями (как в примере выше), так как цифровые ссылки легко могут быть перезаписаны.

Разные имена

Есть некоторые имена серверов, которые обрабатываются особым образом.

Если требуется обрабатывать запросы без поля заголовка «Host» в блоке server, который не является по умолчанию, следует указать пустое имя:

server {
    listen       80;
    server_name  example.org  www.example.org  "";
    ...
}

Если в блоке server не определено server_name, nginx использует пустое имя в качестве имени сервера.

Версии nginx до 0.8.48 использовали имя хоста машины в качестве имени сервера в этом случае.

Если имя сервера определено как «$hostname» (0.9.4), используется имя хоста машины.

Если кто-то отправляет запрос с использованием IP-адреса вместо имени сервера, поле заголовка запроса «Host» будет содержать IP-адрес, и запрос можно обработать, используя IP-адрес в качестве имени сервера:

server {
    listen       80;
    server_name  example.org
                 www.example.org
                 ""
                 192.168.1.1
                 ;
    ...
}

В примерах серверов по умолчанию можно увидеть странное имя «_»:

server {
    listen       80  default_server;
    server_name  _;
    return       444;
}

В этом имени нет ничего особенного, это просто одно из множества некорректных доменных имён, которые никогда не совпадают с реальными именами. Другие некорректные имена, такие как «--» и «!@#», также могут быть использованы.

Версии nginx до 0.6.25 поддерживали специальное имя «*», которое ошибочно интерпретировалось как имя по умолчанию. Оно никогда не работало как имя по умолчанию или имя с подстановкой. Вместо этого оно предоставляло функциональность, которая сейчас предоставляется директивой server_name_in_redirect. Специальное имя «*» теперь устарело, и следует использовать директиву server_name_in_redirect. Обратите внимание, что нет способа указать имя по умолчанию или сервер по умолчанию с помощью директивы server_name. Это свойство директивы listen, а не директивы server_name. Смотрите также «Как nginx обрабатывает запрос». Можно определить серверы, слушающие порты *:80 и *:8080, и указать, что один будет сервером по умолчанию для порта *:8080, а другой — для порта *:80:

server {
    listen       80;
    listen       8080  default_server;
    server_name  example.net;
    ...
}

server {
    listen       80  default_server;
    listen       8080;
    server_name  example.org;
    ...
}

Международные имена

Международные доменные имена (IDN) должны быть указаны с использованием ASCII (Punycode) представления в директиве server_name:

server {
    listen       80;
    server_name  xn--e1afmkfd.xn--80akhbyknj4f;  # пример.испытание
    ...
}

Выбор виртуального сервера

Сначала соединение создается в контексте сервера по умолчанию. Затем имя сервера может быть определено на следующих этапах обработки запроса, каждый из которых участвует в выборе конфигурации сервера:

  • во время рукопожатия SSL, заранее, в соответствии с SNI

  • после обработки строки запроса

  • после обработки поля заголовка Host

  • если имя сервера не было определено после обработки строки запроса или из поля заголовка Host, nginx будет использовать пустое имя в качестве имени сервера.

На каждом из этих этапов могут применяться различные конфигурации серверов. Поэтому некоторые директивы следует указывать с осторожностью:

  • в случае директивы ssl_protocols, список протоколов устанавливается библиотекой OpenSSL до того, как конфигурация сервера может быть применена в соответствии с именем, запрошенным через SNI, таким образом, протоколы следует указывать только для сервера по умолчанию;
  • директивы client_header_buffer_size и merge_slashes участвуют до чтения строки запроса, таким образом, эти директивы используют конфигурацию сервера по умолчанию или конфигурацию сервера, выбранную через SNI;
  • в случае директив ignore_invalid_headers, large_client_header_buffers и underscores_in_headers, участвующих в обработке полей заголовка запроса, дополнительно зависит, была ли конфигурация сервера обновлена в соответствии со строкой запроса или с полем заголовка Host;
  • ответ об ошибке будет обработан с помощью директивы error_page на сервере, который в настоящее время выполняет запрос.

Оптимизация

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

Сначала ищется хеш-таблица точных имён. Если имя не найдено, ищется хеш-таблица имён с подстановкой, начинающихся со звёздочки. Если имя не найдено там, ищется хеш-таблица имён с подстановкой, заканчивающихся звёздочкой.

Поиск в хеш-таблице имён с подстановкой медленнее, чем поиск в хеш-таблице точных имён, потому что имена ищутся по частям домена. Обратите внимание, что специальная форма имени с подстановкой «.example.org» хранится в хеш-таблице имён с подстановкой, а не в хеш-таблице точных имён.

Регулярные выражения проверяются последовательно и, следовательно, являются самым медленным и не масштабируемым методом.

По этим причинам лучше использовать точные имена, где это возможно. Например, если наиболее часто запрашиваемые имена сервера — example.org и www.example.org, эффективнее определить их явно:

server {
    listen       80;
    server_name  example.org  www.example.org  *.example.org;
    ...
}

чем использовать упрощённую форму:

server {
    listen       80;
    server_name  .example.org;
    ...
}

Если определено большое количество имён серверов или определены необычно длинные имена серверов, может потребоваться настройка директив server_names_hash_max_size и server_names_hash_bucket_size на уровне http. Значение по умолчанию для директивы server_names_hash_bucket_size может быть равно 32, 64 или другому значению в зависимости от размера строки кэша CPU. Если значение по умолчанию равно 32, а имя сервера определено как «too.long.server.name.example.org», nginx не сможет запуститься и выведет сообщение об ошибке:

could not build the server_names_hash,
you should increase server_names_hash_bucket_size: 32

В этом случае значение директивы следует увеличить до следующей степени двойки:

http {
    server_names_hash_bucket_size  64;
    ...

Если определено большое количество имён серверов, появится другое сообщение об ошибке:

could not build the server_names_hash,
you should increase either server_names_hash_max_size: 512
or server_names_hash_bucket_size: 32

В таком случае сначала попробуйте установить server_names_hash_max_size на значение, близкое к количеству имён серверов. Только если это не поможет, или время запуска nginx неприемлемо велико, попробуйте увеличить server_names_hash_bucket_size.

Если сервер является единственным сервером для порта прослушивания, то nginx вообще не будет проверять имена серверов (и не будет создавать хеш-таблицы для порта прослушивания). Однако есть одно исключение. Если имя сервера — это регулярное выражение с захватами, nginx должен выполнить выражение, чтобы получить захваты.

Совместимость

  • Специальное имя сервера “$hostname” поддерживается с версии 0.9.4.
  • Значение имени сервера по умолчанию — пустое имя «» с версии 0.8.48.
  • Захваты по имени в именах серверов-регулярных выражениях поддерживаются с версии 0.8.25.
  • Захваты в именах серверов-регулярных выражениях поддерживаются с версии 0.7.40.
  • Пустое имя сервера «» поддерживается с версии 0.7.12.
  • Дикий символ в имени сервера или регулярное выражение поддерживаются в качестве первого имени сервера с версии 0.6.25.
  • Имена серверов-регулярные выражения поддерживаются с версии 0.6.7.
  • Дикий символ в форме example.* поддерживается с версии 0.6.0.
  • Специальная форма .example.org поддерживается с версии 0.3.18.
  • Дикий символ в форме *.example.org поддерживается с версии 0.1.13.
написано Игорем Сысоевым
отредактировано Брайаном Мерсером

© 2002-2021 Igor Sysoev
© 2011-2024 Nginx, Inc.
Licensed under the BSD License.
https://nginx.org/en/docs/http/server_names.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API