Múltiples VirtualHost en SSL en una única IP (SNI)

Resumiendo mucho el funcionamiento de los VirtualHost en Apache, se puede decir que el cliente (nuestro navegador) envía al servidor el nombre del dominio al que deseamos acceder y Apache lo busca en sus configuraciones para entregarte la web. De esta forma en un solo servidor podemos tener alojados múltiples páginas web, cada una con su VirtualHost.

GET /blog/ HTTP/1.1
Host: miguelangelnieto.net
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; es-ES; rv:1.9.0.6) Gecko/2009020911 Firefox/3.0.6
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: es,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

Pero la cosa cambia si las webs deben ser transmitidas mediante HTTPS, esto es, estableciendo una conexión SSL. Gracias a esta tecnología es posible que todo el tráfico entre el servidor y nuestro navegador vaya cifrado y esta es la raíz del problema. Al tener todos los datos cifrados, el servidor no puede saber que dominio está pidiendo el navegador, por lo que los VirtualHost en base a nombres (dominios) pierden utilidad. Para paliar este problema, se ponían múltiples IPs en el servidor y se asignaba cada IP a un VirtualHost. De esta forma, cada web HTTPS tenia como destino una IP distinta y así el servidor era capaz de darte la web que estabas buscando. Esto es, se pasaba de tener VirtualHost por nombre a tenerlos por IP. Si tenías dos páginas web esto no era problema, pero si tenías 200... acelerarías la implantación de IPV6 y eso no es bueno 😉

Para solucionar este problema se publicó en 2006 el RFC 4366. En resumen, TLS pasaba a tener extensiones a nivel cliente y servidor. Una de las cuales permite que el cliente en el establecimiento de la conexión (antes de comenzar el cifrado) pueda indicar el dominio al que desea acceder. La que nos hace la magia es SNI. Para que esto funcione es necesario cumplir una serie de requisitos:

  • OpenSSL 0.9.8f o posterior con extensiones TLS (enable-tlsext)
  • Apache compilado con dicho OpenSSL
  • Navegadores Mozilla Firefox 2.0, Opera 8.0 Internet Explorer 7.0, Google Chome, Safari 3.2.1

Para activar esta extensión añadimos la siguiente línea a httpd.conf:

SSLStrictSNIVHostCheck on

Una vez hecho configuraríamos nuestros VirtualHost SSL como si fuesen los de toda la vida (sin SSL).

Listen 443
NameVirtualHost *:443
<VirtualHost *:443>
        ServerName test1.irontec.com
        ServerAlias test1.irontec.com
        DocumentRoot /var/www/test1
        Options FollowSymLinks
        <Directory /var/www/test1>
        AllowOverride All
        </Directory>
        ErrorLog /var/log/apache2/test1error.log
        CustomLog /var/log/apache2/test1access.log combined env=!client-ip-request
        SSLEngine on
        SSLCertificateFile /etc/ssl/test.pem
        SSLCertificateKeyFile /etc/ssl/test.key
</VirtualHost>
<VirtualHost *:443>
        ServerName test2.irontec.com 
        ServerAlias test2.irontec.com 
        DocumentRoot /var/www/test2
        Options FollowSymLinks
        <Directory /var/www/test2>
        AllowOverride All
        </Directory>
        ErrorLog /var/log/apache2/test2error.log
        CustomLog /var/log/apache2/test2access.log combined env=!client-ip-request
        SSLEngine on
        SSLCertificateFile /etc/ssl/test.pem
        SSLCertificateKeyFile /etc/ssl/test.key
</VirtualHost>

Si vemos el siguiente error en los logs de Apache es que nuestro navegador no es compatible:

[error] No hostname was provided via SNI for a name based virtual host

Y listo, ya puedes tener múltiples VirtualHost con SSL en una única IP 😀


Comments

    Hola amigo. Te agradezco mucho este post. Me resolviste una gran interrongante. No sé si me puedes colaborar con información de como usar el wordpress para varios VirtualHost en el puerto 80. El primero que se instaló funciona muy bien pero luego descomprimí el contenido del WP en la carpeta del otro Host pero tengo problemas para agregar plugins y themes a pesar de haber configurado el FTP

    Daniel on

    Hola, en realidad esa directiva es solo para permitir el acceso a los clientes (browsers) que no soportan SNI. El SNI está soportado por Apache de facto, pero es necesaria una versión de OpenSSl >=0.9.8k y el Apache compilado contra ésta. Slds!

    p3ntium on

    Excelente articulo, muchas gracias por la publicación.

    Percy on

    Muchísimas gracias!!! No sabía que a partir del 2006 se podían crear virtualhosts en https... la de años que me he perdido :P

    mischorradas on

    Buenas, Creando los virtualhost me aparecen problemas de incompatibilidad y he leído que no es compatible con el navegador Internet Explorer 7.0 desde Windows XP y con Google Chome no consigo hacerlo funcionar, ¿podría no ser compatible?

    Gracias por la info!!

    Sandra on

    Gracias! me has arreglado un problema, 10puntos

    Rafael on

    El manual de Apache indica esto:

    Available in Apache 2.2.12 and later

    Admin on

    Muy buen artículo.

    Pero se me plantea una cuestión: ¿A partir de que versión de Apache tenemos disponible los virtualhost bajo ssl?

    pepe on