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

109

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

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

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

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

Джон
источник
В этом теле Q написано несколько сертификатов, и ответы на них верны. Но в заголовке написано, что несколько доменов и у вас может быть несколько доменов с одним сертификатом (и без SNI), см. Serverfault.com/questions/126072/… и serverfault.com/questions/279722/… также кросс на security.SX.
dave_thompson_085

Ответы:

68

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


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

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

Изменить, чтобы добавить: очевидно, 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.
voretaq7
источник
2
Это очень полезно - спасибо! Любая информация о том, как настроить Apache для TLS вместо SSL?
Джош
2
Я думаю, что Apache 2.2 просто нужно включить биты TLS в своем списке шифров. Я признаю, что никогда не видел весь бит «Обновление с SSL на TLS» в действии, пока эти два сайта все же. Насколько я понимаю, документы TLS таковы, что это допустимая (но необычная) ситуация для согласования такого рода обновлений ...
voretaq7
Это первый раз, когда я видел это, и я все еще пытаюсь оторвать свою челюсть от пола ...
Джош
1
ОК, мой ответ только утроился в длине - очевидно, что curl может выполнять как SSLv3, так и TLSv1, чтобы я мог показать неудачу и успех. Хотелось бы мне иметь под рукой отладчик протокола, чтобы показать магическую часть. (Также протестирован и рад сообщить, что сервер johnlai2004 правильно запрещает соединения SSLv2 :-)
voretaq7
Это очень полезно, и я надеюсь, что johnlai2004 примет ваш ответ. Большое спасибо!
Джош
97

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

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

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

Индикация имени сервера ( 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-адреса?

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

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

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

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

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

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

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

Майкл Хэмптон
источник
1
Намного лучше :-) Надеюсь, это может в конечном итоге получить более высокий балл, чем тот, который принят в настоящее время, что, к сожалению, за исключением последнего редактирования вверху, в большинстве случаев неверно.
Бруно
1
@ Bruno Я, конечно, не буду жаловаться, если ты найдешь несколько сотен человек, которые проголосуют за это. :)
Майкл Хэмптон
В последнем браузере BlackBerry (10?) Используется последняя версия WebKit, поэтому вполне вероятно, что он теперь поддерживает SNI.
dave1010
37

Проблема:

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

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

TLS рукопожатие

Если бы это был 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 клиент отправляет имя сервера, к которому он хочет получить доступ, как часть первого сообщения, шаг «Привет клиент» на диаграмме рукопожатия выше.

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

введите описание изображения здесь

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

Кенни Рассчарт
источник
16

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 
Craig
источник
6

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

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

Сокол Момот
источник
В дополнение к ответу Сокола IIS также требует некоторых специальных изменений, чтобы заставить несколько сайтов IIS работать по одному IP. Вы должны вручную отредактировать файл конфигурации для сервера или использовать инструмент CLI, чтобы внести изменения привязки, инструмент GUI не может сделать это. В IIS это называется назначением сертификатов SSL заголовкам узлов. У Apache не было проблемы некоторое время.
Брент Пабст
Ах, хорошо, это проясняет некоторые. Как узнать, поддерживает ли это клиент (браузер)? Например, если я хочу проверить MSIE6, как я могу проверить это без установки виртуальной машины XP или около того?
Люк
1
@Falcon SNI не работает с IE на XP; на которую по-прежнему приходится почти четверть пользователей настольного Интернета. Я бы не назвал это «широко распространенным», когда четверть потенциальных посетителей не работают.
Крис С
1
@MichaelHampton IE использует собственный криптографический стек Windows для SSL. XP не поддерживает SNI, поэтому ни одна из версий IE под управлением XP также не поддерживает. IE поддерживает только SNI в Vista и более новых ОС.
Крис С