Я столкнулся со странным поведением в 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 не учитывал конечную точку в строке заголовка "Host".
Затем, годы спустя, в журнале изменений 1.5.9 говорится:
Исправление: распознаватель не понимал доменные имена с точкой в конце. Спасибо Ичун Чжан.
Хотя я не уверен, относится ли «преобразователь» к компоненту Nginx, который задействован при получении запроса. (Из чтения документации кажется, что распознаватель ничего не делает, если запрос не перенаправляется на какой-то другой хост, имя которого затем должно быть разрешено.)
Что тут происходит? Должен ли Nginx отбрасывать конечную точку при оценке имен серверов? Если это является предполагаемое поведение, не следует ли также удалять конечную точку из server_name
параметр, чтобы выдать ошибку "конфликтующее имя сервера"?
Я знаю, что доменное имя без конечной точки технически является «относительным» доменным именем, а не «абсолютным», хотя большинство людей в наши дни, кажется, рассматривают их как все относящиеся к .
зона, поэтому это не имеет практического значения. Но разве Nginx не должен, по крайней мере, при желании сделать это различие?
Наконец, есть ли лучший способ перехватывать и перенаправлять запросы на example.com.
чем добавление if ($http_host = 'domain.com.')
? Я был сказал что это неэффективно, так как требует Host
заголовок должен быть оценен дважды.
На уровне DNS example.com
и example.com.
одно и то же имя. Это не просто означает, что они должны обрабатываться одинаково, это означает, что они оба будут кодировать одну и ту же последовательность октетов в пакете DNS. Попытка рассматривать их как разные протоколы, использующие DNS (например, HTTP), гарантированно вызовет путаницу и проблемы.
Если часть программного обеспечения использует имена из DNS и рассматривает одно и то же имя с точкой в конце и без нее как другое, это значит, что в этой программе есть ошибка.
TL; DR;
Это похоже на ошибку Nginx, вероятно, потому, что мало кто знает, что полные доменные имена заканчиваются точкой.
Задний план
Мне пришлось прочитать ваше утверждение «полные доменные имена заканчиваются точкой». я нашел этот полезный ресурс это довольно хорошо объясняет. Также есть SF вопрос и ответ здесь. Кажется, лишь очень небольшое меньшинство (включая меня до сих пор) знали, что в домене может быть даже конечная точка.
Заметка
Обратите внимание, что «заголовок хоста» и «имя_сервера Nginx» совершенно разные. Server_name определяет запросы, на которые сервер Nginx будет отвечать. «Заголовок хоста» - это часть заголовка http, отправляемого клиентом серверу.
пример
Я пробовал ваши примеры серверов с example.com, сопоставленным с моим сервером, с теми же результатами, что и вы на nginx 1.9.11. Я также пробовал с сервером example.com. определено, но не "example.com". Когда я свернул эту конфигурацию, я получил ответ от своего сервера по умолчанию, а не от "example.com". сервер.
Документация
В Документация по nginx server_name не упоминает конечную точку. В документации разрешается использовать подстановочный знак после точки (example.com. *). Интересно, знал ли автор документации о полностью определенных доменных именах.
Теория
Я должен задаться вопросом, определяете ли вы «example.com» и «example.com». в Nginx в чем разница? Предполагается, что example.com - это полный URL-адрес корня DNS, поэтому предполагается, что "." все равно после него.
Вывод
Я думаю, что вы, вероятно, технически правы, что имя сервера Nginx должно соответствовать конечной точке. Я не уверен, что он должен относиться к нему иначе или отличаться от server_name без конечной точки по причинам, изложенным выше.
Похоже, это может быть ошибка в Nginx из-за недосмотра. Это также могло быть преднамеренным, основанным на общей практике, а не на RFC.