/ NGinx

Instalar Ghost en Ubuntu 16.04 - Parte 3 - Cómo activar cifrado SSL en Nginx

Como hace ya un par de años Google anunció que en su algoritmo de búsqueda iba a tener gran importancia en el muestro de resultados el hecho de que las webs tengan cifrado de seguridad, vamos a aprovechar que estamos realizando la instalación de Ghost desde cero para lanzar nuestra web a la luz pública directamente a través de HTTPS en vez de HTTP.

Para que una web HTTPS sea fiable, el certificado de seguridad que la misma incorpora tiene que ser emitido por una entidad de certificación autorizada, y lo normal es que este tipo de certificaciones SSL sean caras. Pero gracias al aval de grandes compañías de la industria de internet, el esfuerzo de la Fundación Linux, y su idea de hacer una red cada vez más segura, tenemos Let's Encrypt, una entidad certificadora que emite certificados SSL gratuitos.

Nosotros vamos a aprovecharlo para crear nuestro propio certificado. La única pega de Let's Encrypt quizás es que el certificado hay que renovarlo cada 90 días, pero no es nada que no se pueda solucionar con una simple tarea de Cron. Además, el propio Certbot te da una herramienta para hacerlo.

Obteción del certificado

Let's Encrypt proporciona una herramienta muy potente llamada Certbot que puedes descargar de forma gratuita desde su web del proyecto. Esta herramienta nos dará todo lo necesario para obtener el certificado, por lo que vamos a seguir paso por paso su tutorial.

Lo primero que haremos es descargar el bot, que en Ubuntu 16.04 ya se incorpora en los repositorios oficiales.

$ sudo apt-get install letsencrypt

Una vez tenemos descargado el bot, tan solo hemos de ejecutarlo para los dominios que queremos certificar.

$ letsencrypt certonly --webroot -w /var/www/ghost -d tudominio.com -d www.tudominio.com

Si todo sale bien, dentro de la ruta del host (/var/www/ghost) se habrá creado un directorio .well_known, oculto a Nginx, donde guardará la información del certificado SSL.

Ahora solo nos queda decirle a NGinx dónde está dicho certificado, y hacer accesible la web a través del mismo. Para ello tendremos que editar nuestro fichero /etc/nginx/sites-availables/ghost y añadir lo siguiente, sustituyendo tudominio.com por tu nombre del sitio:

server {
    # Escuchamos el puerto 443 del SSL
    listen 443 ssl;

    # Indicamos el nombre del dominio a tratar
    server_name tudominio.com www.tudominio.com;

    # Indicamos la ruta donde se encuentran los certificados
    ssl_certificate 
    /etc/letsencrypt/live/tudominio.com/fullchain.pem;
    ssl_certificate_key 
    /etc/letsencrypt/live/eiris.es/privkey.pem;

    # Activamos OCSP stapling como se recomienda en https://community.letsencrypt.org/t/integration-guide/13123 
    ssl_stapling on;
    ssl_stapling_verify on;

    # Uncomment this line only after testing in browsers, as it 
    # commits you to continuing to serve your site over HTTPS in 
    # future add_header Strict-Transport-Security "max-age=31536000";
    add_header Strict-Transport-Security "max-age=31536000";
    # maintain the .well-known directory alias for renewals
    
    # Al igual que el host por el puerto 80, configuramos los logs
    access_log /var/log/nginx/tudominio.com.access combined;
    error_log /var/log/nginx/tudominio.com.error combined;

    # Damos acceso a Nginx al directorio .well-known
    location /.well-known {
        alias /var/www/ghost/.well-known;
    }

    # Configuramos el vhost para que lea del puerto del servidor ghost al igual que con el puerto 80
    location / {
        # proxy commands go here as in your port 80 configuration
        proxy_pass http://localhost:2368;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_buffering off;
    }
}

Tras esta configuración, volvemos a copiar el fichero ghost en el directorio sites-enabled y reiniciamos el NGinx:

$ sudo rm /etc/nginx/sites-enabled/ghost
$ sudo cp /etc/nginx/sites-available/ghost /etc/nginx/sites-enabled/ghost
$ sudo service nginx force-reload

Si todo ha salido bien, ya podrás acceder a tu web a través de HTTPS.

https://tuweb.com

Redirigir todo el tráfico del puerto 80 al puerto 443

Tras tener configurado y funcionando el certificado de Let's Encrypt, una de las tareas importantes es que todo el tráfico que entre a nuestra web, lo haga a través de HTTPS, y no de HTTP como anteriormente. Por ello, vamos a redirigir todo el tráfico de nuestra web del puerto 80 al 443.

Para ello, vamos de nuevo al archivo de configuración de Ghost (/etc/nginx/sites-available/ghost) y añadimos la redirección, de nuevo modificando el nombre de dominio:

server {
    listen 80;
    server_name tudominio.com www.tudominio.com;
    rewrite ^ https://$host$request_uri? permanent;
}

De nuevo, tan solo tendremos que copiar el archivo del vhost en sites-enabled de NGinx y reiniciar el servicio, y ya tendremos todo el tráfico redirigido al puerto 443.

$ sudo rm /etc/nginx/sites-enabled/ghost
$ sudo cp /etc/nginx/sites-available/ghost /etc/nginx/sites-enabled/ghost
$ sudo service nginx force-reload

Renovar automáticamente el certificado

Como comenté, el certificado de Let's Encrypt caduca cada 90 días, y se puede renovar desde el propio bot. Con la siguiente línea podremos comprobar si la renovación desde el bot funciona correctamente. Es importante indicar que como no introdujimos un email en la solicitud del certificado, ahora nos dará un warning, pero este no afecta a la renovación, por lo que no ha de preocuparnos:

$ letsencrypt renew --dry-run --agree-tos

Ahora lo único que debemos hacer es automatizar la tarea de renovación para que cada x días vaya solicitando la renovación. Podemos hacerlo a través del cron semanal de nuestro servidor:

$ sudo nano /etc/cron.weekly/letsencrypt

E introducimos lo siguiente:

#!/bin/bash
# Script de renovación automática de certificaciones Let's Encrypt
letsencrypt renew > /dev/null

Tras esto, le damos a dicho fichero permisos de ejecución y reiniciamos el demonio de Cron:

$ sudo chmod +x /etc/cron.weekly/letsencrypt
$ sudo service cron restart

Y ya tendremos nuestro certificado SSL instalado y con renovación automática.