server_name bug

MZ zuborg at advancedhosters.com
Wed Oct 22 17:06:44 MSD 2008


В ср, 22/10/2008 в 16:25 +0400, Igor Sysoev пишет:
> On Wed, Oct 22, 2008 at 03:04:52PM +0300, MZ wrote:
> 
> > В ср, 22/10/2008 в 15:23 +0400, Igor Sysoev пишет:
> > > On Wed, Oct 22, 2008 at 02:14:36PM +0300, MZ wrote:
> > > 
> > > > В ср, 22/10/2008 в 13:52 +0400, Anton Yuzhaninov пишет:
> > > > > On 22.10.2008 13:20, MZ wrote:
> > > > > > В вт, 21/10/2008 в 22:40 +0400, Igor Sysoev пишет:
> > > > > >> On Tue, Oct 21, 2008 at 09:27:40PM +0300, MZ wrote:
> > > > > >>
> > > > > >>> Обнаружил такой баг
> > > > > >>> server {
> > > > > >>>   listen *:80;
> > > > > >>>   server_name example.org;
> > > > > >>> }
> > > > > >>> server {
> > > > > >>>   listen 1.2.3.4:80;
> > > > > >>>   server_name default;
> > > > > >>> }
> > > > > >>>
> > > > > >>> запрос на 1.2.3.4 с Host: example.org попадает не в первый vhost а во
> > > > > >>> второй
> > > > > >>>
> > > > > >>> nginx 0.6.31
> > > > > >> Это не баг. Сначала проверяются адрес:порт, а только потом имя.
> > > > > >> Поскольку listen 1.2.3.4:80 описан явно, то, с точки зрения nginx'а,
> > > > > >> сервер, в котором он описан, является единственным приёмником таких запросов.
> > > > > > Поскольку присутствует *:80 то приемников для коннектов на 1.2.3.4 уже
> > > > > > не одна штука, а включая все виртхосты с 1.2.3.4:80 и все с *:80.
> > > > > > 
> > > > > >> Особенно хорошо это видно, если поставить
> > > > > >>
> > > > > >>    listen 1.2.3.4:80 default bind;
> > > > > >>
> > > > > >> Тогда соединение в принципе не попадёт в *:80. Так устроены сокеты.
> > > > > 
> > > > > > без bind соединение попадает в *:80, но не обрабатывается первым
> > > > > > виртхостом - разве это не баг ?
> > > > > > 
> > > > > 
> > > > > Нет, то как это происходит сейчас, это наиболее логичное поведение.
> > > > > 
> > > > > Это чем то похоже на more specific route в маршрутизации - если есть
> > > > > маршрут на определенный IP, то используется он, а не default route (аналог *:80).
> > > > > 
> > > > > А чтобы было проще поддерживать конфигурацию старайтесь не смешивать *:80 и явное указание IP,
> > > > > и там где нужно явно указывать default.
> > > > 
> > > > Если уж сравнивать с specific route - то почему сравнивается 1.2.3.4 с *
> > > > (когда запрос приходит на 1.2.3.4) а не "server_name example.org" с
> > > > "server_name nonexample.org" когда в запросе присутвует "Host:
> > > > example.org" ?
> > > 
> > > Потому что IP - первичны, а имена - вторичны.
> > В Вашей интерпретации первычны не IP, а сокеты, поскольку IP 1.2.3.4
> > подходит обоим сокетам *:80 и 1.2.3.4:80.
> 
> Почему ? 1.2.3.4:80 - более приоритетен, чем *:80.
> *:80 - это fallbacki, default route.
Почему? Я знаю Ваш ответ - потому что сокеты так реализованы.

На самом деле приоритет должен быть у того виртхоста у которого
подходящий server_name и listen, а не тот у которого подходящий только
listen. И это проблема реализации не сокетов, а nginx-а, который
выбирает неправильный виртхост. Nginx не должен игнорировать виртхосты с
*:80 только потому что есть виртхосты с конкретно указанным ипом в
listen.

> > В то время как для протокола http все равно какие сокеты как
> > используются, он полагается только на значение хидера Host и работу dns.
> > 
> > > > Я считаю логичным ожидать что запрос попадет в какой-то виртхост по
> > > > соответствию Host с server_name, коли уж оба listen соответствуют ипу на
> > > > который пришел запрос.
> > > 
> > > А как быть с ситуацией, когда запросы начинают обрабатываться по-другому
> > > после добавления в listen параметров ?
> > А в чем проблема ?
> > 
> > Параметры listen влияют только на слушающие сокеты - настраивайте их так
> > как указано в конфиге.
> > 
> > Ведь речь идет только о соответствии определенного виртхоста пришедшему
> > запросу.
> 
> Проблема в том, что две нижеприведённые конфигурации должны работать
> одинаково:
> 
>  server {
>    listen *:80;
>    server_name example.org;
>  }
>  server {
>    listen 1.2.3.4:80;
>    server_name default;
>  }
> 
> 
>  server {
>    listen *:80 default rcvbuf=16k;
>    server_name example.org;
>  }
>  server {
>    listen 1.2.3.4:80 default rcvbuf=8k;
>    server_name default;
>  }
> 
> И они сейчас работают одинаково, несмотря на то, что в первом случае
> используется один сокет, а во втором - два.

Это не проблема, в обоих конфигурациях меняются только параметры
слушающих сокетов, а конфигурация виртхостов сохраняется идентичной и
таковой, что http-запрос с Host: example.org соответствует первому
виртхосту а не второму.


More information about the nginx-ru mailing list