Насколько я понимаю, когда Apache получает запрос на один из TCP-портов, который он прослушивает (например, 80, 443), он решит, какой хост запрашивается, просмотрев заголовок HTTP. Host
. Затем сервер будет знать, на какой виртуальный хост он должен перенаправить запрос.
Но как это работает для HTTP через SSL / TLS? Поскольку весь HTTP-запрос шифруется (по крайней мере, я думаю, что где-то читал), информация заголовка может быть прочитана только после того, как сервер расшифрует данные. Но для расшифровки ему необходимо знать, какую пару ключей использовать, поскольку на веб-сервере может быть установлено несколько сертификатов SSL.
Итак, как сервер узнает, какой ключ ему нужен для расшифровки?
Я мог представить, что рукопожатие TLS предоставляет необходимую информацию.
Хотя я согласен, что ответы как связанный вопрос, так и мой собственный похожи, я должен сказать, что вопрос другой. Не может быть и речи о том, возможен ли хостинг нескольких сайтов с независимыми сертификатами SSL. Вместо этого мой вопрос касается основного технического аспекта.
Первоначально веб-сервер не знал. Это было причиной того, что вам нужен был отдельный IP-адрес для каждого виртуального хоста SSL, который вы хотели разместить на сервере. Таким образом, сервер знал, что при подключении по IP X ему необходимо использовать конфигурацию (включая сертификаты) для связанного виртуального хоста.
Это изменилось с Индикация имени сервера, расширение TLS, которое действительно позволяет клиенту указывать необходимое имя хоста в процессе установления связи. Это расширение используется во всех современных ОС, но старые браузеры или серверы его не поддерживают, поэтому, если вы ожидаете, что клиенты по-прежнему будут использовать IE 6 на WinXP, вам не повезло.
Похоже, у вас есть неправильные представления о TLS / SSL. HTTP-запрос не шифруется открытым ключом сервера. Он зашифрован симметричным шифром с использованием ключа, согласованного в предыдущем рукопожатии.
Краткое описание установления связи TLS: сервер и клиент согласовывают некоторый набор шифров, симметричный ключ (ключи) и некоторые другие детали. Чтобы предотвратить MITM, сервер обычно отправляет свой сертификат (цепочку) клиенту и аутентифицирует рукопожатие, используя ключ в сертификате. (Есть также некоторые другие варианты, например, аутентификация клиента или TLS-PSK, но они мало используются с HTTP.) Клиент может либо проверить сертификат (обычным способом), либо проигнорировать его.
Хотя SNI важен при использовании нескольких сертификатов TLS на одном IP-адресе, для сервера не обязательно иметь возможность расшифровать запрос. Без SNI сервер не знает, какая цепочка сертификатов должна быть отправлена, поэтому сервер обычно выбирает один (например, первый виртуальный хост), который, конечно, может быть неправильным. Если сервер выбирает неправильную цепочку сертификатов, клиент должен отказаться от нее (чтобы он не продолжал отправлять HTTP-запрос). Однако, если клиент игнорирует сертификат (или если недействительный сертификат помечен как доверенный для этого сайта), он может успешно продолжить. Поскольку симметричный ключ, используемый для шифрования, не зависит от сертификата (TLS разработан также для работы без сертификатов), сервер может его расшифровать.
Небольшое замечание, почему я пишу о TLS, а вы спрашивали о SSL: TLS - это новая версия SSL. Все версии SSL считаются небезопасными для общего использования, поэтому сейчас мы в основном используем TLS (1.0, 1.1, 1.2).