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