¿Múltiples dominios SSL en la misma dirección IP y el mismo puerto?

109

Esta es una pregunta canónica sobre el alojamiento de múltiples sitios web SSL en la misma IP.

Tenía la impresión de que cada certificado SSL requería su propia combinación única de dirección IP / puerto. Pero la respuesta a una pregunta anterior que publiqué está en desacuerdo con esta afirmación.

Usando la información de esa pregunta, pude obtener varios certificados SSL para trabajar en la misma dirección IP y en el puerto 443. Estoy muy confundido sobre por qué esto funciona dado el supuesto anterior y reforzado por otros de que cada sitio web de dominio SSL en el El mismo servidor requiere su propia IP / Puerto.

Sospecho que hice algo mal. ¿Se pueden usar múltiples certificados SSL de esta manera?

John
fuente
Este cuerpo Q dice múltiples certs y las respuestas son correctas para eso. Pero el título dice múltiples dominios y puede tener múltiples dominios con un certificado (y sin SNI), consulte serverfault.com/questions/126072/… y serverfault.com/questions/279722/… también cruzan en security.SX.
dave_thompson_085

Respuestas:

68

Para obtener la información más actualizada sobre Apache y SNI, incluidas RFC adicionales específicas de HTTP, consulte el Wiki de Apache


FYsI: La magia de la actualización de TLS le brinda "múltiples (diferentes) certificados SSL en una IP". Funciona con servidores Apache más nuevos (2.2.x) y navegadores razonablemente recientes (no conozco versiones fuera de mi cabeza).

RFC 2817 (actualización a TLS dentro de HTTP / 1.1) tiene los detalles sangrientos, pero básicamente funciona para mucha gente (si no la mayoría).
Sin s_clientembargo, puede reproducir el antiguo comportamiento funky con el comando de openssl (o cualquier navegador "suficientemente viejo").

Editar para agregar: aparentemente curlpuede mostrarte lo que está sucediendo aquí mejor que 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
fuente
2
Eso es muy útil. ¡Gracias! ¿Alguna información sobre cómo configurar Apache para TLS en lugar de SSL?
Josh
2
Creo que Apache 2.2 solo necesita tener los bits TLS habilitados en su lista de cifrado. Sin embargo, admito que nunca he visto todo el bit "Actualización de SSL a TLS" en acción hasta estos dos sitios. Mi comprensión de los documentos TLS es que es una situación permisible (pero poco común) para negociar este tipo de actualización ...
voretaq7
Esta es la primera vez que lo veo y sigo tratando de levantar la mandíbula del suelo ...
Josh
1
OK, mi respuesta se triplicó: aparentemente curl puede hacer negociaciones tanto SSLv3 como TLSv1 para que pueda mostrar el fracaso y el éxito. Sin embargo, desearía tener un depurador de protocolos a mano para mostrar la parte mágica. (También probado y feliz de informar que el servidor de johnlai2004 niega correctamente las conexiones SSLv2 :-)
voretaq7
Eso es extremadamente útil y espero que johnlai2004 acepte su respuesta. ¡Muchas gracias!
Josh
97

Sí, pero hay algunas advertencias.

Esto se logra a través de la Indicación del nombre del servidor, una extensión de Transport Layer Security.

¿Qué es la indicación del nombre del servidor?

La indicación de nombre de servidor ( RFC 6066 ; RFC 4366 obsoleto , RFC 3546 ) es una extensión de Transport Layer Security que permite al cliente decirle al servidor el nombre del host al que está tratando de llegar.

SNI es compatible con TLS 1.0 y superior de acuerdo con las especificaciones, pero las implementaciones pueden variar (ver más abajo). No se puede usar con SSL, por lo que una conexión debe negociar TLS (ver RFC 4346 apéndice E ) para que se use SNI. Esto generalmente ocurre automáticamente con el software compatible.

¿Por qué se necesita SNI?

En una conexión HTTP normal , el navegador informa al servidor del nombre de host del servidor al que está tratando de llegar utilizando el Host:encabezado. Esto permite que un servidor web en una sola dirección IP sirva contenido para múltiples nombres de host, lo que comúnmente se conoce como alojamiento virtual basado en nombres .

La alternativa es asignar direcciones IP únicas para cada nombre de host web que se servirá. Esto se hizo comúnmente en los primeros días de la web, antes de que se supiera ampliamente que las direcciones IP se agotarían y comenzaran las medidas de conservación, y todavía se hace de esta manera para los hosts virtuales SSL (que no usan SNI).

Debido a que este método de transmisión del nombre de host requiere que la conexión ya esté establecida, no funciona con conexiones SSL / TLS. En el momento en que se configura la conexión segura, el servidor web ya debe saber qué nombre de host va a servir al cliente, porque el servidor web está configurando la conexión segura.

SNI resuelve este problema haciendo que el cliente transmita el nombre de host como parte de la negociación de TLS, de modo que el servidor ya sepa qué host virtual se debe utilizar para dar servicio a la conexión. El servidor puede usar el certificado y la configuración para el host virtual correcto.

¿Por qué no usar diferentes direcciones IP?

El Host:encabezado HTTP se definió para permitir que se sirviera más de un host web desde una sola dirección IP debido a la escasez de direcciones IPv4, lo que se reconoció como un problema a mediados de los años noventa. En entornos de alojamiento web compartido, cientos de sitios web únicos y no relacionados pueden ser atendidos utilizando una sola dirección IP de esta manera, conservando el espacio de direcciones.

Los entornos de alojamiento compartido encontraron que el mayor consumidor de espacio de direcciones IP era la necesidad de sitios web seguros para tener direcciones IP únicas, creando la necesidad de SNI como una medida provisional en el camino hacia IPv6. Hoy en día, a veces es difícil obtener tan solo 5 direcciones IP (/ 29) sin una justificación significativa, lo que a menudo resulta en retrasos en la implementación.

Con el advenimiento de IPv6, tales técnicas de conservación de direcciones ya no son necesarias, ya que un solo host puede tener más direcciones IPv6 asignadas de las que hoy contiene todo Internet, pero las técnicas probablemente aún se utilizarán en el futuro para dar servicio a IPv4 heredado conexiones

Advertencias

Algunas combinaciones de sistema operativo / navegador no son compatibles con SNI (ver más abajo), por lo que usar SNI no es apropiado para todas las situaciones. Los sitios que se dirigen a tales combinaciones de sistema / navegador tendrían que renunciar a SNI y continuar usando direcciones IP únicas para cada host virtual.

De particular interés, ninguna versión de Internet Explorer en Windows XP es compatible con SNI. Como esta combinación todavía representa una porción significativa (pero en constante disminución; alrededor del 16% del tráfico de Internet en diciembre de 2012 según NetMarketShare) del tráfico de Internet, SNI sería inapropiado para un sitio dirigido a estas poblaciones de usuarios.

Apoyo

Muchos, pero no todos, los paquetes de software comúnmente utilizados admiten SNI.

(La omisión de esta lista no significa necesariamente falta de soporte; significa que había un límite en cuanto a lo que podía escribir, o no podía encontrar rápidamente la información en una búsqueda. Si su paquete de software no está en la lista, busque por su nombre plus snidebería revelar si existe soporte y cómo configurarlo).

Soporte de biblioteca

La mayoría de los paquetes dependen de una biblioteca externa para proporcionar soporte SSL / TLS.

  • GNU TLS
  • JSSE (Oracle Java) 7 o superior, solo como cliente
  • libcurl 7.18.1 o superior
  • NSS 3.1.1 o superior
  • OpenSSL 0.9.8j o superior
    • OpenSSL 0.9.8f o superior, con banderas de configuración
  • Qt 4.8 o superior

Soporte del servidor

La mayoría de las versiones actuales de software de servidor popular admiten SNI. Las instrucciones de configuración están disponibles para la mayoría de estos:

Soporte al cliente

La mayoría de los navegadores web actuales y los agentes de usuario de línea de comandos admiten SNI.

Escritorio

  • Chrome 5 o superior
    • Chrome 6 o superior en Windows XP
  • Firefox 2 o superior
  • Internet Explorer 7 o superior, que se ejecuta en Windows Vista / Server 2008 o superior
    • Internet Explorer en Windows XP no es compatible con SNI independientemente de la versión de IE
  • Konqueror 4.7 o superior
  • Opera 8 o superior (puede requerir TLS 1.1 habilitado para funcionar)
  • Safari 3.0 en Windows Vista / Server 2008 o superior, o Mac OS X 10.5.6 o superior

Móvil

  • Navegador de Android en 3.0 Honeycomb o superior
  • Safari de iOS en iOS 4 o superior
  • Windows Phone 7 o superior

Línea de comando

  • cURL 7.18.1 o superior
  • wget 1.14 o superior (las distribuciones pueden haber respaldado un parche para soporte SNI)

Sin soporte

  • Navegador BlackBerry
  • Internet Explorer (cualquier versión) en Windows XP

(Nota: Parte de la información para esta respuesta se obtuvo de Wikipedia ).

Michael Hampton
fuente
1
Mucho mejor :-) Afortunadamente, esto eventualmente puede obtener una puntuación más alta que la actualmente aceptada, lo que, aparte de la última edición en la parte superior, es mayormente incorrecto desafortunadamente.
Bruno
1
@Bruno Ciertamente no me quejaré si encuentras unos cientos de personas para votarlo. :)
Michael Hampton
El último navegador BlackBerry (10?) Utiliza una versión reciente de WebKit, por lo que es muy probable que ahora sea compatible con SNI.
dave1010
37

El problema:

Cuando un cliente web y un servidor web se comunican entre sí a través de HTTPS, lo primero que debe suceder es el apretón de manos seguro.

Aquí hay un ejemplo simplificado de tal apretón de manos:

tls apretón de manos

Si esto fuera HTTP y no HTTPS, lo primero que el cliente habría enviado habría sido algo como esto:

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

Esto hizo posible múltiples hosts virtuales en una sola dirección IP, ya que el servidor sabe exactamente a qué dominio quiere acceder el cliente, a saber, example.com.

HTTPS es diferente. Como dije antes, el apretón de manos viene antes que todo lo demás. Si observa el tercer paso del protocolo de enlace ilustrado anteriormente (Certificado), el servidor debe presentar un certificado al cliente como parte del protocolo de enlace, pero no tiene idea de qué nombre de dominio está intentando acceder el cliente. La única opción que tiene el servidor es enviar el mismo certificado cada vez, su certificado predeterminado.

Aún podría configurar hosts virtuales en su servidor web, pero el servidor siempre enviaría el mismo certificado a cada cliente. Si trató de alojar los sitios web example.com y example.org en su servidor, el servidor siempre enviaría el certificado de example.com cuando un cliente solicita una conexión HTTPS. Entonces, cuando un cliente solicita example.org a través de una conexión HTTPS establecida, esto sucedería:

ingrese la descripción de la imagen aquí

Este problema limita efectivamente la cantidad de dominios que puede servidor a través de HTTPS a uno por dirección IP.

La solución:

La forma más fácil de resolver este problema es que el cliente le diga al servidor a qué dominio quiere acceder durante el protocolo de enlace . De esta manera, el servidor puede entregar el certificado correcto.

Esto es exactamente lo que hace SNI o Indicación de nombre de servidor.

Con SNI, el cliente envía el nombre del servidor al que desea acceder como parte del primer mensaje, el paso "Cliente Hola" en el diagrama de protocolo de enlace anterior.

Algunos navegadores web más antiguos no son compatibles con SNI. Por ejemplo, en Windows XP no hay una única versión de Internet Explorer que sea compatible con SNI. Al acceder a un recurso a través de HTTPS en un servidor que utiliza hosts virtuales SNI, se le presentará un certificado genérico, lo que puede hacer que el navegador muestre una advertencia o error.

ingrese la descripción de la imagen aquí

He simplificado las cosas aquí solo para explicar el principio detrás del problema y la solución. Si desea una explicación más técnica, la página de wikipedia o RFC 6066 pueden servir como buenos puntos de partida. También puede encontrar una lista actualizada de servidores y navegadores que admiten SNI en wikipedia

Kenny Rasschaert
fuente
16

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

El navegador del cliente también debe ser compatible con SNI. Aquí hay algunos navegadores que lo hacen:

* 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
fuente
6

La extensión TLS de indicación de nombre de servidor (RFC6066) es necesaria para que los vhosts basados ​​en nombre funcionen a través de HTTPS.

La extensión está ampliamente implementada y aún no he encontrado ningún problema con el software actual, pero existe la posibilidad de que algunos clientes (aquellos que no lo admitan) se enruten a su sitio predeterminado si depende de SNI.

Falcon Momot
fuente
Además de la respuesta de Falcon, IIS también requiere algunos cambios especiales para que varios sitios IIS funcionen sobre la misma IP. Debe editar manualmente el archivo de configuración para el servidor o utilizar una herramienta CLI para realizar los cambios de enlace, la herramienta GUI no puede hacerlo. En IIS se le denomina asignación de certificados SSL a los encabezados de host. Apache no ha tenido el problema por un tiempo.
Brent Pabst
Ah, está bien, eso aclara un poco. ¿Cómo puede saber si un cliente (navegador) es compatible con esto? Por ejemplo, si quiero verificar MSIE6, ¿cómo puedo probar eso sin tener que instalar una máquina XP virtual o algo así?
Luc
1
@Falcon SNI no funciona con IE en XP; que todavía representa casi una cuarta parte de los usuarios de Internet de escritorio. No lo llamaría "ampliamente implementado" cuando una cuarta parte de los visitantes potenciales no funcionan.
Chris S
1
@MichaelHampton IE utiliza la pila de cifrado nativa de Windows para SSL. XP no es compatible con SNI, por lo tanto, ninguna versión de IE que ejecute XP tampoco. IE solo admite SNI en Vista y sistemas operativos más nuevos.
Chris S