Имена сервера
Имена с масками Имена, заданные регулярными выражениями Прочие имена Интернационализованные имена Выбор виртуального сервера Оптимизация Совместимость |
Имена сервера задаются с помощью директивы 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$; ... }
При поиске виртуального сервера по имени, если имени соответствует несколько из указанных вариантов, например, одновременно подходят и имя с маской, и регулярное выражение, будет выбран первый подходящий вариант в следующем порядке приоритета:
- точное имя
-
самое длинное имя с маской в начале, например
“
*.example.org
” -
самое длинное имя с маской в конце, например “
mail.*
” - первое подходящее регулярное выражение (в порядке следования в конфигурационном файле)
Имена с масками
Имя с маской может содержать звёздочку (“*
”) только в начале
или в конце имени, и только на границе, определяемой точкой.
Имена “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 поддерживает именованные выделения, используя следующий синтаксис:
Если nginx отказывается запускаться и выдаёт сообщение об ошибке:
?<
name
>Совместимый с Perl 5.10 синтаксис, поддерживается начиная с PCRE-7.0 ?'
name
'Совместимый с Perl 5.10 синтаксис, поддерживается начиная с PCRE-7.0 ?P<
name
>Python-совместимый синтаксис, поддерживается начиная с PCRE-4.0
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_name не задана в блоке server, то nginx будет использовать пустое имя в качестве имени сервера.
Версии nginx вплоть до 0.8.48 в этом случае использовали имя хоста (hostname) машины в качестве имени сервера.
Если имя сервера задано как “$hostname
” (0.9.4), то
используется имя хоста (hostname) машины.
Если в запросе вместо имени сервера указан 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; ... }
Интернационализованные имена
Для указания интернационализированных доменных имён (IDNs) в директиве server_name следует указывать Punycode-представление имени:
server { listen 80; server_name xn--e1afmkfd.xn--80akhbyknj4f; # пример.испытание ... }
Выбор виртуального сервера
Сначала соединение создаётся в контесте сервера по умолчанию. Затем имя сервера может быть определено на следующих стадиях обработки запроса, каждая из которых участвует в выборе конфигурации:
-
предварительно во время операции SSL handshake согласно 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, либо другой величине,
в зависимости от размера строки кэша процессора.
Если значение по умолчанию равно 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.
автор: Игорь Сысоев редактор: Brian Mercer |