Имена сервера
| Имена с масками Имена, заданные регулярными выражениями Прочие имена Интернационализованные имена Выбор виртуального сервера Оптимизация Совместимость |
Имена сервера задаются с помощью директивы 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 |