У меня есть 1 одиночная машина с ИП 1.2.3.4. Эта машина имеет 2 веб-сервера и ftp-сервер:
Веб-сервер 1 прослушивает порт 82; домен для него: ws1.example.com
Веб-сервер 2 прослушивает порт 83; домен для него: ws2.example.com
FTP-сервер прослушивает порт 21; домен для него: ftp.example.com
Вот как выглядит сопоставление DNS:
ws1.example.com CNAME example.com
ws2.example.com CNAME example.com
ftp.example.com CNAME example.com
example.com A 1.2.3.4
Дело 1: Я делаю запрос по URL-адресу браузера ws1.example.com:82, и DNS перенаправляет меня на пример.com, но с заголовком Хозяин: ws1.example.com.
Случай 2: Я делаю запрос по URL-адресу браузера ws2.example.com:83, и DNS перенаправляет меня на пример.com, но с заголовком Хозяин: ws2.example.com.
В обоих случаях:
запрос в конечном итоге достигает той же физической машины
когда приходит запрос:
В случае 1 запрос поступает на этот компьютер, и запрос обрабатывается приложением, которое прослушивает порт 82, то есть веб-сервер 1.
В случае 2 запрос поступает на этот компьютер, и запрос обрабатывается приложением, которое прослушивает порт 83, то есть веб-сервер 2.
Заголовок Хозяин, как я понимаю, используется для информирования принимающего хоста, чтобы определить, какой сервер (из нескольких серверов, на которых размещался этот IP) предназначен для этого запроса и, соответственно, направляет запрос соответствующему приложению.
Мой вопрос:
В этом примере, какова цель заголовка Хозяин, поскольку одна и та же физическая машина с одним и тем же IP-адресом имеет несколько приложений, прослушивающих соответствующие порты. Как только запрос достигнет этой машины, соответствующий порт в любом случае поднимется, а другие приложения проигнорируют запрос, поскольку порт не соответствует запросу. Итак, для какой цели здесь служит заголовок Хозяин, когда соответствующие порты в любом случае делают свою работу правильно и хорошо?
Могу ли я сделать вывод, что
имеет смысл только тогда, когда вы используете что-то вроде обратного прокси, например. 1 машина взаимодействует с клиентом и перенаправляет пользовательские запросы на соответствующий веб-сервер на отдельных машинах, все прослушивают один и тот же порт, например. 80, каждый в сети за обратным прокси-сервером, и в этом случае у вас есть ws1.example.com и ws2.exmple.com, оба перенаправляются на обратный прокси-сервер пример.com, и этот обратный прокси-сервер теперь перенаправляет их на соответствующий хост на основе заголовка Хозяин?
Сначала важное исправление терминологии:
В DNS нет "редиректов". В вашем случае DNS просто используется для сопоставления имени с IP-адресом. Иногда из-за CNAME имя сопоставляется с другим именем, которое затем сопоставляется с IP-адресом. Неважно, есть ли такие промежуточные шаги, в конце имя сопоставляется с IP (или происходит сбой разрешения DNS)
Это также означает, что если URL-адрес имеет определенный порт, то он не изменяется, окончательный IP-адрес будет запрашиваться через порт, указанный в URL-адресе.
Перенаправления — это функция уровня http: при запросе веб-сервера для https://www.mygreatsite.example/foo
он ответит кодом возврата HTTP 301, 302, 303, 307 или 308 и предоставит вам (клиенту HTTP, также известному как браузер) новый URL-адрес для перехода.
В старые добрые времена IP-адресов было предостаточно. Если бы вы размещали и www.site1.example
, и www.site2.example
на одном и том же физическом поле, вы могли бы привязать к каждому из них один IP-адрес разные.
Следовательно, в этом конкретном случае заголовок HTTP host
в каком-то смысле бесполезен, сам факт подключения либо к 192.0.2.37
, либо к 192.0.2.42
уже позволяет узнать, какой сайт вам нужен.
На самом деле в HTTP/0.9
не было host
заголовка, как не было заголовков вообще.
Но затем, когда в игру вступает массовый виртуальный хостинг, а адресов IPv4 становится все меньше, вы больше не можете привязывать один единственный IP-адрес к сайту, так как это тоже пустая трата времени.
Таким образом, через DNS, прямо или косвенно (CNAME
записи), оба веб-сайта разрешались на один и тот же IP-адрес.
Следовательно, когда HTTP-клиент подключается к серверу, сервер по умолчанию не может узнать, какой веб-сайт вам нужен. Вот почему заголовок HTTP host
, заполненный клиентом, позволяет серверу узнать, к какому веб-сайту вы хотите получить доступ, независимо к его IP-адресу, который был разрешен ранее через DNS.
По умолчанию HTTP использует порт 80, поэтому он часто не виден в URL-адресах.
Конечно, если бы вы заставили своих клиентов использовать http://www.site1.example:4569
с одной стороны и http://www.anothersite2.com:9873
с другой стороны, то вы правы, заголовок host
был бы не нужен.
За исключением того, что план падает по многим причинам:
Следовательно, обычно это делается не так, если вы хотите предоставить какой-либо сервис через HTTP, но в порту, отличном от порта по умолчанию, вы обычно устанавливаете перед ним обратный прокси-сервер. Или вы делаете HTTP-перенаправление с http://www.coolpublicname.example/
на http://www.complicatedinternalname.example:9713
, но тогда клиент видит эту голую правду.
Попутно отметим, что HTTPS добавил уровень сложности, потому что веб-сервер HTTPS должен отправить свой сертификат клиенту, но, поскольку каждый веб-сайт может иметь другой сертификат, ему необходимо знать, какой веб-сайт хочет использовать клиент, который он может узнать через host
HTTP-заголовок, но затем появляется после завершения рукопожатия TLS, поэтому на ранней стадии отправки сертификата сервером это еще недоступно.
Таким образом, в самые ранние времена HTTPS мы были вынуждены снова использовать виртуальный хостинг на основе IP, а не виртуальный хостинг на основе имени, как это было возможно в чистом HTTP благодаря заголовку host
.
Решение было найдено с помощью расширения TLS, индикации имени сервера (SNI), чего-то, что клиент отправляет на сервер заранее и дает имя веб-сайта, чтобы сервер мог отправить соответствующий сертификат, и, следовательно, мы снова в деле в случай, основанный на имени, когда у вас теоретически может быть бесконечное количество имен, разрешающих один и тот же IP-адрес, чтобы они обслуживались одним заданным веб-сервером.