Назад | Перейти на главную страницу

Несколько доменов SSL на одном IP-адресе и одном порте?

Это Канонический вопрос о размещении нескольких веб-сайтов SSL на одном IP.

У меня сложилось впечатление, что каждый сертификат SSL требует собственной уникальной комбинации IP-адреса / порта. Но ответ на предыдущий вопрос, который я отправил расходится с этим утверждением.

Используя информацию из этого вопроса, я смог получить несколько сертификатов SSL для работы с одним и тем же IP-адресом и на порту 443. Я очень смущен тем, почему это работает, учитывая приведенное выше предположение и подкрепленное другими, что каждый веб-сайт домена SSL на тому же серверу требуется собственный IP / порт.

Я подозреваю, что сделал что-то не так. Можно ли таким образом использовать несколько сертификатов SSL?

Да, но есть некоторые оговорки.

Это достигается с помощью индикации имени сервера, расширения безопасности транспортного уровня.

Что такое индикация имени сервера?

Индикация имени сервера (RFC 6066; устаревший RFC 4366, RFC 3546) является расширением Безопасность транспортного уровня что позволяет клиенту сообщить серверу имя хоста, которого он пытается достичь.

SNI совместим с TLS 1.0 и выше в соответствии со спецификацией, но реализации могут отличаться (см. Ниже). Его нельзя использовать с SSL, поэтому соединение должно согласовывать TLS (см. RFC 4346, приложение E) для использования SNI. Обычно это происходит автоматически с поддерживаемым программным обеспечением.

Зачем нужен SNI?

В нормальном HTTP соединение, браузер сообщает серверу имя хоста сервера, к которому он пытается подключиться, используя Host: заголовок. Это позволяет веб-серверу на одном IP-адресе обслуживать контент для нескольких имен хостов, что обычно известно как виртуальный хостинг на основе имени.

Альтернативой является назначение уникальных IP-адресов для каждого обслуживаемого имени веб-хоста. Это обычно делалось в самые ранние дни Интернета, до того, как стало широко известно, что IP-адреса закончатся, и начались меры по сохранению, и до сих пор это делается для виртуальных хостов SSL (без использования SNI).

Поскольку этот метод передачи имени хоста требует, чтобы соединение было уже установлено, он не работает с соединениями SSL / TLS. К моменту установки безопасного соединения веб-сервер должен уже знать, какое имя хоста он будет обслуживать клиенту, поскольку сам веб-сервер устанавливает безопасное соединение.

SNI решает эту проблему, заставляя клиента передавать имя хоста как часть согласования TLS, так что сервер уже знает, какой виртуальный хост должен использоваться для обслуживания соединения. Затем сервер может использовать сертификат и конфигурацию для правильного виртуального хоста.

Почему бы не использовать разные IP-адреса?

HTTP Host: Заголовок был определен таким образом, чтобы с одного IP-адреса можно было обслуживать более одного веб-хоста из-за нехватки адресов IPv4, признанной проблемой еще в середине 1990-х годов. В средах общего веб-хостинга сотни уникальных, не связанных между собой веб-сайтов могут обслуживаться с использованием одного IP-адреса, таким образом сохраняя адресное пространство.

Затем среды общего хостинга обнаружили, что крупнейшим потребителем пространства IP-адресов была потребность в защищенных веб-сайтах с уникальными IP-адресами, что создавало потребность в SNI в качестве временной меры на пути к IPv6. Сегодня иногда сложно получить всего 5 IP-адресов (/ 29) без значительного обоснования, что часто приводит к задержкам в развертывании.

С появлением IPv6 в таких методах сохранения адресов больше нет необходимости, поскольку одному узлу может быть назначено больше адресов IPv6, чем сегодня содержится во всем Интернете, но эти методы, вероятно, будут использоваться еще далеко в будущем для обслуживания устаревшего IPv4. соединения.

Предостережения

Некоторые комбинации операционной системы и браузера не поддерживают SNI (см. Ниже), поэтому использование SNI подходит не для всех ситуаций. Сайты, нацеленные на такие комбинации системы / браузера, должны будут отказаться от SNI и продолжать использовать уникальные IP-адреса для каждого виртуального хоста.

Особо следует отметить, что ни одна из версий Internet Explorer в Windows XP не поддерживает SNI. Поскольку эта комбинация все еще представляет собой значительную (но неуклонно снижающуюся; около 16% интернет-трафика в декабре 2012 года по данным NetMarketShare) часть интернет-трафика, SNI не подходит для сайта, ориентированного на эти группы пользователей.

Служба поддержки

Многие, но не все, широко используемые программные пакеты поддерживают SNI.

(Отсутствие в этом списке не обязательно означает отсутствие поддержки; это означает, что был предел того, сколько я мог ввести, или я не мог быстро найти информацию в поиске. Если вашего программного пакета нет в списке, выполните поиск за его имя плюс sni должен показать, существует ли поддержка и как ее настроить.)

Поддержка библиотеки

Большинство пакетов зависят от внешней библиотеки для обеспечения поддержки SSL / TLS.

  • GNU TLS
  • JSSE (Oracle Java) 7 или выше, только как клиент
  • libcurl 7.18.1 или выше
  • NSS 3.1.1 или выше
  • OpenSSL 0.9.8j или выше
    • OpenSSL 0.9.8f или выше, с флагами конфигурации
  • Qt 4.8 или выше

Поддержка сервера

Большинство последних версий популярного серверного программного обеспечения поддерживают SNI. Инструкции по установке доступны для большинства из них:

Служба поддержки клиентов

Большинство современных веб-браузеров и пользовательских агентов командной строки поддерживают SNI.

Рабочий стол

  • Chrome 5 или выше
    • Chrome 6 или выше в Windows XP
  • Firefox 2 или выше
  • Internet Explorer 7 или новее, работает под управлением Windows Vista / Server 2008 или новее
    • Internet Explorer в Windows XP не поддерживает SNI независимо от версии IE
  • Konqueror 4.7 или выше
  • Opera 8 или выше (для работы может потребоваться TLS 1.1)
  • Safari 3.0 в Windows Vista / Server 2008 или новее или Mac OS X 10.5.6 или новее

Мобильный

  • Браузер Android на 3.0 Honeycomb или выше
  • iOS Safari на iOS 4 или выше
  • Windows Phone 7 или выше

Командная строка

  • cURL 7.18.1 или выше
  • wget 1.14 или выше (в дистрибутивах может быть патч для поддержки SNI)

Нет поддержки

  • Браузер BlackBerry
  • Internet Explorer (любая версия) в Windows XP

(Примечание: некоторая информация для этого ответа была получена из Википедия.)

Самую свежую информацию об Apache и SNI, включая дополнительные RFC для HTTP, см. В Apache Wiki


FYsI: «Несколько (разных) сертификатов SSL на одном IP-адресе» - это волшебство обновления TLS. Он работает с более новыми серверами Apache (2.2.x) и достаточно свежими браузерами (не знаю версий, которые мне нравятся).

RFC 2817 (обновление до TLS в HTTP / 1.1) содержит подробности, но в основном он работает для многих (если не для большинства).
Вы можете воспроизвести старое фанковое поведение с помощью openssl s_client команда (или любой "достаточно старый" браузер) хотя.

Изменить, чтобы добавить: очевидно curl может показать вам, что здесь происходит лучше, чем openssl:


SSLv3

mikeg@flexo% curl -v -v -v -3 https://www.yummyskin.com
* About to connect() to www.yummyskin.com port 443 (#0)
*   Trying 69.164.214.79... connected
* Connected to www.yummyskin.com (69.164.214.79) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: /usr/local/share/certs/ca-root-nss.crt
  CApath: none
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using DHE-RSA-AES256-SHA
* Server certificate:
*    subject: serialNumber=wq8O9mhOSp9fY9JcmaJUrFNWWrANURzJ; C=CA; 
              O=staging.bossystem.org; OU=GT07932874;
              OU=See www.rapidssl.com/resources/cps (c)10;
              OU=Domain Control Validated - RapidSSL(R);
              CN=staging.bossystem.org
*    start date: 2010-02-03 18:53:53 GMT
*    expire date: 2011-02-06 13:21:08 GMT
* SSL: certificate subject name 'staging.bossystem.org'
       does not match target host name 'www.yummyskin.com'
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):
curl: (51) SSL: certificate subject name 'staging.bossystem.org'
does not match target host name 'www.yummyskin.com'

TLSv1

mikeg@flexo% curl -v -v -v -1 https://www.yummyskin.com
* About to connect() to www.yummyskin.com port 443 (#0)
*   Trying 69.164.214.79... connected
* Connected to www.yummyskin.com (69.164.214.79) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: /usr/local/share/certs/ca-root-nss.crt
  CApath: none
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using DHE-RSA-AES256-SHA
* Server certificate:
*    subject: C=CA; O=www.yummyskin.com; OU=GT13670640;
              OU=See www.rapidssl.com/resources/cps (c)09;
              OU=Domain Control Validated - RapidSSL(R);
              CN=www.yummyskin.com
*    start date: 2009-04-24 15:48:15 GMT
*    expire date: 2010-04-25 15:48:15 GMT
*    common name: www.yummyskin.com (matched)
*    issuer: C=US; O=Equifax Secure Inc.; CN=Equifax Secure Global eBusiness CA-1
*    SSL certificate verify ok.

Эта проблема:

Когда веб-клиент и веб-сервер общаются друг с другом по HTTPS, самый первый то, что должно произойти, - это безопасное рукопожатие.

Вот упрощенный пример такого рукопожатия:

Если бы это был HTTP, а не HTTPS, первое, что отправил бы клиент, было бы примерно так:

GET /index.html HTTP/1.1
Host: example.com

Это сделало возможным создание нескольких виртуальных хостов на одном IP-адресе, поскольку сервер точно знает, к какому домену клиент хочет получить доступ, а именно example.com.

HTTPS - другое дело. Как я сказал ранее, рукопожатие предшествует всему остальному. Если вы посмотрите на третий этап рукопожатия, показанный выше (Сертификат), сервер должен представить сертификат клиенту как часть рукопожатия, но не имеет понятия, к какому доменному имени клиент пытается получить доступ. Единственный вариант, который имеет сервер, - это отправлять каждый раз один и тот же сертификат, сертификат по умолчанию.

Вы все еще можете настроить виртуальные хосты на своем веб-сервере, но сервер всегда будет отправлять один и тот же сертификат каждому клиенту. Если вы попытались разместить на своем сервере веб-сайты example.com и example.org, сервер всегда будет отправлять сертификат для example.com, когда клиент запрашивает HTTPS-соединение. Поэтому, когда клиент запрашивает example.org через установленное соединение HTTPS, это может произойти:

Эта проблема фактически ограничивает количество доменов, которые вы можете обслуживать через HTTPS, до одного на каждый IP-адрес.

Решение:

Самый простой способ решить эту проблему - сообщить серверу, к какому домену он хочет получить доступ. во время рукопожатия. Таким образом, сервер сможет выдать правильный сертификат.

Это именно то, что SNI, или указание имени сервера.

С помощью SNI клиент отправляет имя сервера, к которому он хочет получить доступ, как часть первого сообщения, шага «Client Hello» на приведенной выше диаграмме подтверждения.

Некоторые старые веб-браузеры не поддерживают SNI. Например, в Windows XP есть не одна версия Internet Explorer с поддержкой SNI. При доступе к ресурсу через HTTPS на сервере, который использует виртуальные хосты SNI, вам будет представлен общий сертификат, который может вызвать отображение в браузере предупреждения или ошибки.

Я здесь упростил, чтобы просто объяснить принцип, лежащий в основе проблемы и ее решение. Если вам нужно более техническое объяснение, википедия страница или RFC 6066 может служить хорошей отправной точкой. Вы также можете найти обновленный список серверов и браузеров, поддерживающих SNI, на википедия

http://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI

Клиентский браузер также должен поддерживать SNI. Вот некоторые браузеры, которые умеют:

* Mozilla Firefox 2.0 or later
* Opera 8.0 or later (with TLS 1.1 enabled)
* Internet Explorer 7.0 or later (on Vista, not XP)
* Google Chrome
* Safari 3.2.1 on Mac OS X 10.5.6 

Указание имени сервера (RFC6066) TLS-расширение требуется для виртуальных хостов на основе имен для работы через HTTPS.

Расширение широко внедрено, и я еще не сталкивался с какими-либо проблемами с текущим программным обеспечением, но есть вероятность, что некоторые клиенты (не поддерживающие его) будут перенаправлены на ваш сайт по умолчанию, если вы зависите от SNI.