- Имена сервера
- Имена с масками
- Имена, заданные регулярными выражениями
- Прочие имена
- Интернационализованные имена
- Выбор виртуального сервера
- Оптимизация
- Почему nginx отвечает на любое доменное имя?
- 6 ответов
- ** РЕДАКТИРОВАТЬ **
- Server names
- Wildcard names
- Regular expressions names
- Miscellaneous names
- Internationalized names
- Virtual server selection
- Optimization
Имена сервера
Имена сервера задаются с помощью директивы server_name и определяют, в каком блоке server будет обрабатываться тот или иной запрос. См. также “Как nginx обрабатывает запросы”. Имена могут быть заданы точно, с помощью маски или регулярного выражения:
При поиске виртуального сервера по имени, если имени соответствует несколько из указанных вариантов, например, одновременно подходят и имя с маской, и регулярное выражение, будет выбран первый подходящий вариант в следующем порядке приоритета:
- точное имя
- самое длинное имя с маской в начале, например “ *.example.org ”
- самое длинное имя с маской в конце, например “ mail.* ”
- первое подходящее регулярное выражение (в порядке следования в конфигурационном файле)
Имена с масками
Имя с маской может содержать звёздочку (“ * ”) только в начале или в конце имени, и только на границе, определяемой точкой. Имена “ www.*.example.org ” и “ w*.example.org ” являются некорректными, но их можно задать с помощью регулярных выражений, например, “
^w.*\.example\.org$ ”. Звёздочка может соответствовать нескольким частям имени. Имени с маской “ *.example.org ” соответствует не только www.example.org , но и www.sub.example.org .
Специальное имя с маской вида “ .example.org ” соответствует как точному имени “ example.org ”, так и маске “ *.example.org ”.
Имена, заданные регулярными выражениями
Регулярные выражения, используемые в nginx, совместимы с используемыми в языке программирования Perl (PCRE). Имя сервера, заданное регулярным выражением, должно начинаться с символа тильды:
в противном случае оно будет рассматриваться как точное, или же, если выражение содержит звёздочку (“ * ”), то как имя с маской (и, скорее всего, некорректное). Не забывайте ставить специальные символы начала (“ ^ ”) и конца (“ $ ”) строки. По синтаксису они не требуются, но логически они могут быть нужны. Также заметьте, что все точки в доменных именах должны быть экранированы символом обратной косой черты. Регулярное выражение, содержащее символы “ < ” и “ >”, необходимо экранировать:
иначе nginx откажется запускаться и выдаст сообщение об ошибке:
К именованному выделению в регулярном выражении можно впоследствии обратиться через переменную:
Библиотека PCRE поддерживает именованные выделения, используя следующий синтаксис:
? name > Совместимый с Perl 5.10 синтаксис, поддерживается начиная с PCRE-7.0 ?’ name ‘ Совместимый с Perl 5.10 синтаксис, поддерживается начиная с PCRE-7.0 ?P name > Python-совместимый синтаксис, поддерживается начиная с PCRE-4.0
то это значит, что используется старая версия библиотеки PCRE и следует вместо этого попробовать синтаксис “ ?P name > ”. Также можно использовать нумерованные выделения:
Однако такое использование должно ограничиваться простыми случаями как в примере выше, поскольку нумерованные выделения легко могут быть перезаписаны.
Прочие имена
Некоторые имена имеют специальное значение.
Если необходимо обрабатывать запросы без поля “Host” в заголовке в блоке server, который не является сервером по умолчанию, следует указать пустое имя:
Если директива server_name не задана в блоке server, то nginx будет использовать пустое имя в качестве имени сервера.
Версии nginx вплоть до 0.8.48 в этом случае использовали имя хоста (hostname) машины в качестве имени сервера.
Если имя сервера задано как “ $hostname ” (0.9.4), то используется имя хоста (hostname) машины.
Если в запросе вместо имени сервера указан IP-адрес, то поле “Host” заголовка запроса будет содержать IP-адрес, и запрос можно обработать, используя IP-адрес как имя сервера:
В примерах конфигурации серверов, обрабатывающих все запросы, встречается странное имя “ _ ”:
Оно не является каким-то особенным, это просто одно из множества некорректных доменных имён, которые никогда не пересекутся ни с одним из реальных имён. С тем же успехом можно использовать имена типа “ — ” и “ !@# ”.
Версии nginx вплоть до 0.6.25 поддерживали специальное имя “ * ”, которое многими неверно воспринималось как имя сервера для обработки всех запросов. Оно никогда так не работало, и не работало как имя с маской. Это имя действовало так же, как сейчас действует директива server_name_in_redirect. Специальное имя “ * ” объявлено устаревшим, а вместо него следует использовать директиву server_name_in_redirect. Заметьте, что с помощью директивы server_name нельзя задать ни имя сервера для обработки всех запросов, ни сервер по умолчанию. Это является свойством директивы listen, а не server_name. См. также “Как nginx обрабатывает запросы”. Можно настроить серверы, слушающие на портах *:80 и *:8080, и указать, что один из них будет сервером по умолчанию для порта *:8080, а другой — для порта *:80:
Интернационализованные имена
Для указания интернационализированных доменных имён (IDNs) в директиве server_name следует указывать Punycode-представление имени:
Выбор виртуального сервера
Сначала соединение создаётся в контесте сервера по умолчанию. Затем имя сервера может быть определено на следующих стадиях обработки запроса, каждая из которых участвует в выборе конфигурации:
предварительно во время операции 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_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 откажется запускаться и выдаст сообщение об ошибке:
В этом случае следует увеличить значение директивы до следующей степени двойки:
Если задано большое число имён серверов, то будет выдано другое сообщение об ошибке:
В таком случае сначала следует попробовать установить server_names_hash_max_size в величину, близкую к числу имён серверов, и только если это не поможет или время запуска nginx станет неприемлемо большим, следует попытаться увеличить server_names_hash_bucket_size.
Если сервер является единственным сервером для слушающего порта, то nginx не будет проверять имена сервера вообще (а также не будет строить хэш-таблицы для слушающего порта). За одним исключением: если имя сервера задано регулярным выражением с выделениями, то nginx’у придётся выполнить это выражение, чтобы получить значения выделений.
Источник
Почему nginx отвечает на любое доменное имя?
У меня есть nginx, работающий с приложением Ruby /Sinatra, и все хорошо. Тем не менее, сейчас я пытаюсь запустить второе приложение с того же сервера, и я заметил нечто странное. Во-первых, вот мой nginx.conf:
Обратите внимание, как для server_name установлено значение FAKE.COM пока сервер отвечает всем хостам, которые обращаются к этому серверу через другие доменные имена. Как я могу заставить этот конкретный сервер отвечать только на запросы для FAKE.COM ?
6 ответов
Первый блок сервера в конфигурации nginx используется по умолчанию для всех запросов, поступающих на сервер, для которого нет конкретного блока сервера.
Таким образом, в вашей конфигурации предполагается, что вашим реальным доменом является REAL.COM, когда пользователь вводит его, он будет преобразован в ваш сервер, и, поскольку для этой настройки нет блока сервера, блок сервера для FAKE.COM, будучи первым блоком сервера (в вашем случае единственным блоком сервера), обработает этот запрос.
Именно поэтому в правильных конфигах Nginx есть определенный блок сервера для значений по умолчанию, прежде чем переходить к другим для определенных доменов.
** РЕДАКТИРОВАТЬ **
Кажется, что некоторые пользователи немного смущены этим примером и думают, что он ограничен одним файлом conf и т. д.
Обратите внимание, что вышеприведенный пример является простым примером для разработки OP по мере необходимости.
Лично я использую отдельные файлы vhost conf с этим (CentOS /RHEL):
/etc/nginx/conf.d/ будет содержать domain_1.conf, domain_2.conf . domain_n.conf, который будет включен после блока сервера в Основной файл nginx.conf, который всегда будет первым и всегда будет по умолчанию, если он не переопределен директивой default_server в другом месте.
Алфавитный порядок имен файлов conf-файлов для других серверов в этом случае становится неактуальным.
Кроме того, эта схема дает большую гибкость в том смысле, что можно определить несколько значений по умолчанию.
В моем конкретном случае у меня Apache прослушивает порт 8080 только на внутреннем интерфейсе, и я передаю скрипты PHP и Perl в Apache.
Однако я запускаю два отдельных приложения, которые оба возвращают ссылки с «: 8080» в выходном html-файле, когда они обнаруживают, что Apache не работает на стандартном порту 80, и пытаются «помочь» мне.
Это вызывает проблему, заключающуюся в том, что ссылки становятся недействительными, поскольку Apache не может быть доступен с внешнего интерфейса, и ссылки должны указывать на порт 80.
Я решил эту проблему, создав сервер по умолчанию для порта 8080, чтобы перенаправлять такие запросы.
Поскольку ничто в обычных серверных блоках не прослушивает порт 8080, серверный блок по умолчанию для перенаправления прозрачно обрабатывает такие запросы благодаря своей позиции в nginx.conf.
У меня фактически есть четыре таких серверных блока, и это упрощенный вариант использования.
У вас должен быть сервер по умолчанию для catch-all , вы можете вернуть 404 или лучше не делать ответить вообще (сэкономит некоторую пропускную способность), возвращая 444 , который является HTTP-ответом nginx, который просто закрывает соединение и ничего не возвращает
Мне не удалось решить мою проблему с помощью других ответов. Я решил проблему, проверив, подходит ли хост, и вернул 403, если это не так. (У меня был какой-то случайный веб-сайт, указывающий на содержимое моего веб-сервера. Я предполагаю, что он перехватит поисковый рейтинг)
Существует несколько способов указать сервер по умолчанию.
Первый способ . Укажите сервер по умолчанию первым в списке, если настройки сервера хранятся в одном файле конфигурации, как показано выше в Dayo.
Второй способ (лучше) Более гибкий — укажите параметр default_server для listen инструкция, например:
Дополнительная информация здесь: Nginx doc /Listen
Этот способ более полезен, когда вы храните конфигурации сервера в отдельных файлах и не хотите называть эти файлы в алфавитном порядке.
Небольшой комментарий для ответа:
если у вас есть несколько виртуальных хостов на нескольких IP-адресах в нескольких конфигурационных файлах в sites-available /, то домен «по умолчанию» для IP будет взят из первого файла в алфавитном порядке.
И, как сказал Павел, для директивы «listen» есть аргумент «default_server» http://nginx.org/en/docs/http/ngx_http_core_module.html#listen
Чтобы ответить на ваш вопрос — nginx выбирает первый сервер, если нет совпадений. См. документацию :
Если его значение не совпадает ни с одним именем сервера, или запрос не соответствует вообще содержать это поле заголовка, тогда nginx направит запрос в сервер по умолчанию для этого порта. В приведенной выше конфигурации сервер по умолчанию — первый .
Теперь, если вы хотите иметь стандартный универсальный сервер, который, скажем, отвечает 404 на все запросы, вот как это сделать:
Обратите внимание, что вам нужно указать сертификат /ключ (который может быть самоподписанным), в противном случае все SSL-соединения не будут работать, так как nginx попытается принять соединение с помощью этого сервера по умолчанию и не найдет сертификат /ключ.
Источник
Server names
Server names are defined using the server_name directive and determine which server block is used for a given request. See also “How nginx processes a request”. They may be defined using exact names, wildcard names, or regular expressions:
When searching for a virtual server by name, if name matches more than one of the specified variants, e.g. both wildcard name and regular expression match, the first matching variant will be chosen, in the following order of precedence:
- exact name
- longest wildcard name starting with an asterisk, e.g. “ *.example.org ”
- longest wildcard name ending with an asterisk, e.g. “ mail.* ”
- first matching regular expression (in order of appearance in a configuration file)
Wildcard names
A wildcard name may contain an asterisk only on the name’s start or end, and only on a dot border. The names “ www.*.example.org ” and “ w*.example.org ” are invalid. However, these names can be specified using regular expressions, for example, “
^w.*\.example\.org$ ”. An asterisk can match several name parts. The name “ *.example.org ” matches not only www.example.org but www.sub.example.org as well.
A special wildcard name in the form “ .example.org ” can be used to match both the exact name “ example.org ” and the wildcard name “ *.example.org ”.
Regular expressions names
The regular expressions used by nginx are compatible with those used by the Perl programming language (PCRE). To use a regular expression, the server name must start with the tilde character:
otherwise it will be treated as an exact name, or if the expression contains an asterisk, as a wildcard name (and most likely as an invalid one). Do not forget to set “ ^ ” and “ $ ” anchors. They are not required syntactically, but logically. Also note that domain name dots should be escaped with a backslash. A regular expression containing the characters “ < ” and “ >” should be quoted:
otherwise nginx will fail to start and display the error message:
A named regular expression capture can be used later as a variable:
The PCRE library supports named captures using the following syntax:
? name > Perl 5.10 compatible syntax, supported since PCRE-7.0 ?’ name ‘ Perl 5.10 compatible syntax, supported since PCRE-7.0 ?P name > Python compatible syntax, supported since PCRE-4.0
this means that the PCRE library is old and the syntax “ ?P name > ” should be tried instead. The captures can also be used in digital form:
However, such usage should be limited to simple cases (like the above), since the digital references can easily be overwritten.
Miscellaneous names
There are some server names that are treated specially.
If it is required to process requests without the “Host” header field in a server block which is not the default, an empty name should be specified:
If no server_name is defined in a server block then nginx uses the empty name as the server name.
nginx versions up to 0.8.48 used the machine’s hostname as the server name in this case.
If a server name is defined as “ $hostname ” (0.9.4), the machine’s hostname is used.
If someone makes a request using an IP address instead of a server name, the “Host” request header field will contain the IP address and the request can be handled using the IP address as the server name:
In catch-all server examples the strange name “ _ ” can be seen:
There is nothing special about this name, it is just one of a myriad of invalid domain names which never intersect with any real name. Other invalid names like “ — ” and “ !@# ” may equally be used.
nginx versions up to 0.6.25 supported the special name “ * ” which was erroneously interpreted to be a catch-all name. It never functioned as a catch-all or wildcard server name. Instead, it supplied the functionality that is now provided by the server_name_in_redirect directive. The special name “ * ” is now deprecated and the server_name_in_redirect directive should be used. Note that there is no way to specify the catch-all name or the default server using the server_name directive. This is a property of the listen directive and not of the server_name directive. See also “How nginx processes a request”. It is possible to define servers listening on ports *:80 and *:8080, and direct that one will be the default server for port *:8080, while the other will be the default for port *:80:
Internationalized names
Internationalized domain names (IDNs) should be specified using an ASCII (Punycode) representation in the server_name directive:
Virtual server selection
First, a connection is created in a default server context. Then, the server name can be determined in the following request processing stages, each involved in server configuration selection:
during SSL handshake, in advance, according to SNI
after processing the request line
after processing the Host header field
if the server name was not determined after processing the request line or from the Host header field, nginx will use the empty name as the server name.
At each of these stages, different server configurations can be applied. As such, certain directives should be specified with caution:
- in case of the ssl_protocols directive, the protocol list is set by the OpenSSL library before the server configuration could be applied according to the name requested through SNI, thus, protocols should be specified only for a default server;
- the client_header_buffer_size and merge_slashes directives are involved before reading the request line, thus, such directives use a default server configuration or the server configuration chosen by SNI;
- in case of the ignore_invalid_headers, large_client_header_buffers, and underscores_in_headers directives involved in processing request header fields, it additionally depends whether the server configuration was updated according to the request line or the Host header field;
- an error response will be handled with the error_page directive in the server that currently fulfills the request.
Optimization
Exact names, wildcard names starting with an asterisk, and wildcard names ending with an asterisk are stored in three hash tables bound to the listen ports. The sizes of hash tables are optimized at the configuration phase so that a name can be found with the fewest CPU cache misses. The details of setting up hash tables are provided in a separate document.
The exact names hash table is searched first. If a name is not found, the hash table with wildcard names starting with an asterisk is searched. If the name is not found there, the hash table with wildcard names ending with an asterisk is searched.
Searching wildcard names hash table is slower than searching exact names hash table because names are searched by domain parts. Note that the special wildcard form “ .example.org ” is stored in a wildcard names hash table and not in an exact names hash table.
Regular expressions are tested sequentially and therefore are the slowest method and are non-scalable.
For these reasons, it is better to use exact names where possible. For example, if the most frequently requested names of a server are example.org and www.example.org , it is more efficient to define them explicitly:
than to use the simplified form:
If a large number of server names are defined, or unusually long server names are defined, tuning the server_names_hash_max_size and server_names_hash_bucket_size directives at the http level may become necessary. The default value of the server_names_hash_bucket_size directive may be equal to 32, or 64, or another value, depending on CPU cache line size. If the default value is 32 and server name is defined as “ too.long.server.name.example.org ” then nginx will fail to start and display the error message:
In this case, the directive value should be increased to the next power of two:
If a large number of server names are defined, another error message will appear:
In such a case, first try to set server_names_hash_max_size to a number close to the number of server names. Only if this does not help, or if nginx’s start time is unacceptably long, try to increase server_names_hash_bucket_size.
If a server is the only server for a listen port, then nginx will not test server names at all (and will not build the hash tables for the listen port). However, there is one exception. If a server name is a regular expression with captures, then nginx has to execute the expression to get the captures.
Источник