Почему Nginx игнорирует конечные точки в заголовке «Host»?

Я столкнулся со странным поведением в Nginx с запросами, у которых в имени хоста есть конечная точка, например domain.com. а не только domain.com . Я установил простую конфигурацию сервера для тестирования, например:

server {
    listen 80;
    server_name example.com.;
    root /var/www/example;
    index server1.txt;
}

server {
    listen 80;
    server_name example.com;
    root /var/www/example;
    index server2.txt;
}

Изначально я ожидал, что запросы будут сделаны на example.com. будут отправлены в первый блок, а запросы, сделанные на example.com , будут отправлены во второй. Запросы, чей заголовок Host не соответствует ни одному блоку, например www.example.com , я ожидал, что они будут снова отправлены в первый блок, поскольку это было неявным значением по умолчанию.

Однако во время тестирования я обнаружил, что запросы сделаны на example.com. вместо этого были отправлены во второй блок . После долгого экспериментирования с различными альтернативными именами, регулярными выражениями и т. Д. Я решил записать переменную $ host в настраиваемый заголовок, чтобы я мог посмотреть на нее. Оказывается, Nginx на самом деле удаляет конечную точку из значения $ host . Насколько я могу судить, запрос получен на example.com. считается идентичным полученному на example.com , по крайней мере, в отношении выбора сервера. Это кажется нежелательным, поскольку конечные точки могут приводить к различным ошибкам. .

Чтобы сделать ситуацию еще более запутанной, после некоторого поиска в Google я обнаружил страницу журнала изменений Nginx , которая имеет в журнале изменений 0.1.29:

Исправление: nginx не учитывал конечную точку в " Строка заголовка хоста.

Затем, годы спустя, в журнале изменений 1.5.9 говорится:

Исправление: распознаватель не понимал доменные имена с конечной точкой. Спасибо Ичунь Чжану.

Хотя я не уверен, что " Но разве Nginx не должен, по крайней мере, иметь возможность делать это различие при желании?

Наконец, есть ли лучший способ перехватывать и перенаправлять запросы, сделанные на example.com. чем добавление if ($ http_host = 'domain.com.') ? Мне сказали , что это неэффективно, так как требует, чтобы заголовок Host проверялся дважды.

2
задан 13 April 2017 в 15:14
2 ответа

TL; DR;

Это похоже на ошибку Nginx, вероятно, потому что мало кто знает, что полные доменные имена заканчиваются точкой.

Общие сведения

Мне пришлось прочитать ваше утверждение «полные доменные имена заканчиваются точкой». Я нашел этот полезный ресурс , который довольно хорошо это объясняет. Здесь также есть вопрос и ответ SF . Кажется, лишь очень небольшое меньшинство (включая меня до сих пор) знали, что в домене может быть даже конечная точка.

Примечание

Обратите внимание, что «заголовок хоста» и «имя_сервера Nginx» сильно отличаются. Server_name определяет запросы, на которые сервер Nginx будет отвечать. «Заголовок хоста» является частью http-заголовка, отправляемого клиентом на сервер.

Пример

Я пробовал ваши серверы-примеры, с example.com, сопоставленным с моим сервером, с теми же результатами, что и вы на nginx 1.9 .11. Я также пробовал с сервером example.com. определено, но не "example.com". Когда я свернул эту конфигурацию, я получил ответ от своего сервера по умолчанию, а не от "example.com". сервер.

Документация

В документации Nginx имя_сервера не упоминается конечная точка. В документации разрешается использовать подстановочный знак после точки (example.com. *). Интересно, знал ли тот, кто написал документацию, о полностью определенных доменных именах.

Теория

Я должен задаться вопросом, определяете ли вы «example.com» и «example.com». в Nginx в чем разница? Предполагается, что example.com - это полный URL-адрес корня DNS, поэтому предполагается, что "." в любом случае после него.

Заключение

Я думаю, вы, вероятно, технически правы, что имя сервера Nginx должно учитывать конечную точку. Я не уверен, что он должен обрабатывать его иначе или отличным от server_name без конечной точки по причинам, изложенным выше.

Похоже, что это может быть ошибка в Nginx в результате недосмотра. Это также может быть преднамеренным, основанным на общепринятой практике, а не на RFC .

2
ответ дан 3 December 2019 в 09:58

На уровне DNS, example.com и example.com. одно и то же имя. Это не просто означает, что они должны обрабатываться одинаково, это означает, что они оба будут кодировать одну и ту же последовательность октетов в пакете DNS. Попытка рассматривать их как разные в протоколах, использующих DNS (например, HTTP), гарантированно вызовет путаницу и проблемы.

Если часть программного обеспечения использует имена из DNS и обрабатывает одно и то же имя с точкой в ​​конце и без нее. в отличие от этого, в этом программном обеспечении есть ошибка.

2
ответ дан 3 December 2019 в 09:58

Теги

Похожие вопросы