Webs seguras con SSL

Cuando por algun motivo necesitamos que nuestra web sea accesible mediante conexiones cifradas, debemos activar el soporte SSL en nuestro servidor web Apache

Generación de un certificado

Tenemos dos opciones. Crear nuestro certificado firmado por nuestra propia autoridad certificadora, o crear una solicitud de certificado y que la firme una entidad externa, que puede ser de pago o no.

Si solo necesitamos un certificado, podemos utilizar una utilidad de Apache que nos generará un certificado autofirmado. Esto lo hacemos siguiendo las instrucciones que aparecen al ejecutar:


apache2-ssl-certificate
	

Si por el contrario necesitamos varios certificados, crearemos nuestra propia entidad de certificación, rellenando los datos que nos pide la ejecución de este comando.


/usr/lib/ssl/misc/CA.pl -newca
	

Nos creará un directorio demoCA que contendrá la clave privada de nuestra entidad, necesaria para firmar peticiones de certificados.

Ahora creamos un certificado:


/usr/lib/ssl/misc/CA.pl -newreq
	

Cuando nos pida "Common Name", debemos introducir el nombre del dominio para el que se usará este certificado. Es decir, tiene que coincidir con el campo ServerName del virtualhost.

Y lo firmamos con nuestra autoridad certificadora:


/usr/lib/ssl/misc/CA.pl -signreq
	

Llegados a este punto tendremos dos ficheros; newreq.pem y newcert.pem. El fichero newreq.pem contiene la clave privada y el certificado sin firmar. Por su parte, el fichero newcert.pem contiene los datos del certificado, y el certificado en sí firmado por la autoridad certificadora que creamos al principio.

Hay múltiples posibilidades para almacenar los certificados, desde eliminar datos innecesarios y unir los dos ficheros, hasta dejarlos tal cual por separado. Generalmente los programas que utilizan SSL permiten ambas configuraciones

Copiamos newreq.pem a /etc/ssl/private/clave.key y newcert.pem a /etc/ssl/certs/cert.pem. Asimismo nos será util tener a mano el certificado de nuestra entidad certificadora. Para ello copiamos ./demoCA/cacert.pem a /etc/ssl/certs/ca.pem

Configuración de apache2

Dado que el soporte actual se hace mediante SSL, existe una limitación a la hora de crear virtualhosts para páginas cifradas. El chequeo de certificado se hace antes de comprobar el host virtual, lo que implica que sólo podemos utilizar un certificado para todos nuestros virtualhosts. Esto dará lugar a que algunos navegadores avisen de que el certificado de nuestra página no se corresponde con su dirección, como en el caso de yahoo. (El certificado de mail.yahoo.com está expedido para login.yahoo.com). Una solución es que cada virtualhost que necesite cifrado utilice un puerto distinto. De este modo para https://ejemplo.com:443 (puerto por defecto) se usará un certificado diferente al de https://ejemplo.com:10443, de modo que el navegador no pondrá objeciones. Ahora bien, los usuarios son reacios a recordar dirección+puerto, así que podemos usar redirects de apache, de modo que http://ejemplo.com sea redirigido a https://ejemplo.com:10443. Esto es tan fácil como añadir una línea como esta en el virtualhost de ejemplo.com:


Redirect / https://host2.com:10443
	

Obviamente debemos añadir los puertos necesarios en /etc/apache2/ports.conf


Listen 443
Listen 10443
	

Y crear unos virtualhosts similares a éste: (observar las diferencias entre ambos)


<VirtualHost *:443>
  ServerAdmin webmaster@ejemplo1.com
  ServerName ejemplo1.com
  DocumentRoot /var/www/ejemplo1.com
    SSLEngine On
    SSLCertificateFile /etc/ssl/certs/ejemplo1.com.pem
    SSLCertificateKeyFile /etc/ssl/private/host1.com.key
    SSLCACertificateFile /etc/ssl/certs/ca.pem
</VirtualHost>

<VirtualHost *:10443>
  ServerAdmin webmaster@ejemplo2.com
  ServerName ejemplo2.com
  DocumentRoot /var/www/ejemplo1.com
    SSLEngine On
    SSLCertificateFile /etc/ssl/certs/ejemplo2.com.pem
    SSLCertificateKeyFile /etc/ssl/private/host2.com.key
    SSLCACertificateFile /etc/ssl/certs/ca.pem
</VirtualHost>
	

La solución anterior es relativamente compleja, pero si nuestra entidad certificadora nos lo permite podemos utilizar el mismo certificado para varios sitios web, de modo que será el mismo para todos los virtualhost, eliminando el problema de raíz. Si los dominios que alojamos están registrados por diferentes clientes no tenemos mucho que hacer, pero si tenemos control sobre todos los dominios que alojamos, ésta puede ser una solución. CaCert permite emitir certificados de forma gratuíta. Simplemente debemos enviar una solicitud de certificado para varios dominios (todos en la misma solicitud). Este script nos facilitará la tarea.

Para información actualizada acerca del soporte SSL para virtualhosts, visitar esta página.

En este momento tenemos todo configurado, pero apache nos pedirá la clave de los certificados cada vez que lo iniciemos, de modo que no se podrá automatizar el inicio del servidor. Para evitar esto, podemos eliminar la clave de dicho certificado, asegurándonos de ajustar bien los permisos del fichero para que nadie sin autorización pueda acceder a nuestro certificado.


     openssl rsa -in cert.key -out certnopass.key
	

Importante

Si deseamos activar las últimas versiones de TLS (1.1 y 1.2), debemos instalar el paquete libapache2-mod-gnutls, activar el módulo en apache y configurar el virtualhost de la siguiente manera, eliminando las líneas que hacen referencia al motor de cifrado SSL


<VirtualHost *:443>
  ServerAdmin webmaster@ejemplo1.com
  ServerName ejemplo1.com
  DocumentRoot /var/www/ejemplo1.com
  
  GnuTLSEnable on
  GnuTLSPriorities NORMAL
  GnuTLSCertificateFile /etc/ssl/certs/ejemplo1.com.pem
  GnuTLSKeyFile /etc/apache2/ssl/private/ejemplo1.com.key
</VirtualHost>