Añadiendo SSL a tu sitio con Let's Encrypt en NGINX

Let's Encrypt, según ellos mismos se definen es una autoridad certificadora. Se caracteriza por ser libre, automatizada y abierta.

En este tutorial usaremos Let's Encrypt para mandar todo nuestro tráfico a HTTPS gracias a los certificados que nos provee y a su debida configuración en NGINX.

Prerequisitos

Para realizar el tutorial, asumimos que contamos con:

  • Un servidor que funcione con Ubuntu 14.04 LTS
  • Nginx instalado en el servidor.
  • Nginx sirviendo un archivo, por ejemplo un index.html. Puedes usar esta plantilla para servir un Hello World.
  • En el caso de que cuentes con un grupo de seguridad en tu servidor debes de tener habilitado los puertos de HTTP y HTTPS por defecto, es decir, el puerto 80 y el puerto 443.

Instalando el certbot en nuestro servidor

Desde la documentación de Let's Encrypt se nos recomienda generar los certificados usando el cliente Certbot. Si no te gusta su procedimiento o tienes algunos fallos que te impiden finalizar el proceso al final de este tutorial tienes en un enlace todos los clientes con los que puedes generar certificados ACME, que son la base de Let's Encrypt. Hay incluso versiones web, si te sientes más cómodo.

La terminal es tu mejor aliada. Cuanto antes te familiarices con ella antes descubrirás el tiempo que te va a ahorrar en tus futuros desarrollos. Si tienes algunas dudas sobre el uso de la terminal no dudes en dejarlas al final de este artículo.

Descargamos el certbot con este comando:

wget https://dl.eff.org/certbot-auto

Le damos permisos con el comando chmod:

chmod a+x certbot-auto  

Generamos el certificado con el certbot

Una vez que tenemos la herramienta para generar nuestros certificados descargada ya podemos empezar a generarlos. Aunque antes debes de tener en cuenta algunas cosas:

  • El dominio a certificar debe de apuntar al servidor. Puedes comprobarlo con el comando dig example.com

  • Los puertos 80 y 443, como mencioné antes deben de estar habilitados en el grupo de seguridad en el caso de que tu servidor cuente con ellos.

  • No debes de estar sirviendo nada en ninguno de los puertos mencionados. Si quieres parar NGINX solo tienes que correr el comando service nginx stop.

¡Vamos a generar nuestro certificado!

./certbot-auto certonly

Nota: La primera vez puede tardar un poco. Ten en cuenta que tiene que instalar todas las dependencias que necesita.

Elegimos la segunda opción, es decir, Automatically use a temporary webserver(standalone) así nos evitamos hacer una configuración en nuestro NGINX que luego tendríamos que borrar. Mejor que Certbot se encargue de todo:

Tras esto te solicitará algunos datos como tu email y el dominio para el que quieres generar el certificado. Pueden ser varios, con que estén todos apuntando a tu servidor no hay ningún problema:

¡Ya hemos acabado de generar el certificado! Si todo salió bien veras algo parecido a esto:

IMPORTANT NOTES:  
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/prueba.miguhruiz.xyz/fullchain.pem. Your cert
   will expire on 2016-12-03. To obtain a new or tweaked version of
   this certificate in the future, simply run certbot-auto again. To
   non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Adaptando nuestra configuración de NGINX para soportar SSL

Partiendo de un archivo de configuración de NGINX que sirve un index.html:

server {  
  listen 80;
  server_name prueba.miguhruiz.xyz;

  location / {
    root /home/MiguhRuiz;
    index index.html;
  }
}

Lo que tendríamos que hacer principalmente es cambiar el listen 80; por un listen 443 ssl; y añadirle los certificados que necesita, nos quedaría algo como lo siguiente:

server {  
  listen 443 ssl;
  server_name prueba.miguhruiz.xyz;
  ssl_certificate     /etc/letsencrypt/live/prueba.miguhruiz.xyz/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/prueba.miguhruiz.xyz/privkey.pem;

  location / {
    root /home/MiguhRuiz;
    index index.html;
  }
}

Extra: Redirigiendo tu tráfico desde HTTP a HTTPS

No podemos evitar que la gente entre por HTTP, es más nadie se preocupa por escribir https:// por lo que los navegadores nos conectan al puerto 80 por defecto. Afortunadamente si podemos redirigir todo el tráfico añadiendo otro archivo de configuración a NGINX:

server {  
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
}

Tras esto reiniciamos NGINX para que haga caso a esta última modificación:

service nginx restart  

Extra: Añadiendo Full SSL(Strict) a tu sitio(Solo si usas Cloudflare):

En el caso de que estés usando CloudFlare ya sabrás que CloudFlare cifra las conexiones usando SSL.

Ahora que tenemos nuestro certificado en el servidor podemos mejorar el sistema de CloudFlare pasándolo a Full SSL(Strict) de manera que todas las partes por las que pasan la conexión serán seguras, como puedes ver en esta imagen:

Para esto habilitamos este sistema en la configuración de SSL en Cloudflare:

Extra: Sirviendo nuestro contenido usando HTTP2(Solo para versiones de NGINX superiores a 1.9.5)

Solo tenemos que hacer una pequeña modificación la cual es añadir http2 en la línea de listen de manera que nuestro archivo quedaría así:

server {  
  listen 443 ssl http2;
  server_name prueba.miguhruiz.xyz;
  ssl_certificate     /etc/letsencrypt/live/prueba.miguhruiz.xyz/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/prueba.miguhruiz.xyz/privkey.pem;

  location / {
    root /home/MiguhRuiz;
    index index.html;
  }
}

Como bien dije necesitas tener una versión de NGINX superior a 1.9.5, si al reiniciar el proceso de NGINX no puedes habilitarlo probablemente es porque tu versión es inferior a la mencionada.

Enlaces relacionados

Let's Encrypt

CertBot

ACME Client Software Alternatives - Let's Encrypt

Using Free SSL/TLS Certificates from Let’s Encrypt with NGINX - NGINX Blog

Configuring HTTPS servers - NGINX Docs

Open Source NGINX 1.9.5 Released with HTTP/2 Support - NGINX Blog