Configuración Let’s Encrypt óptima

Aunque los certificados de Let’s Encrypt son gratuitos, podemos usarlos, pero debemos hacer que den el máximo rendimiento de seguridad a nuestro WordPress.

Si queremos sacarle el máximo partido no deberemos usar el certificado que se genera por defecto, sino que deberemos hacer y activar algunas configuraciones extra.

Recuerda que los certificados no son compatibles con navegadores muy antiguos, pero que si tienes usuarios que usan dispositivos modernos no debe darte problema.

Este tutorial ha sido creado en un VPS de Clouding.io. Puedes crear tu propio VPS desde 3€/mes.

Además, tienes la posibilidad de crear tu VPS con la imagen de WordPress en un clic.

COLABORACIÓN

Instalación

Para esta prueba en Ubuntu 20, vamos a instalar simplemente un nginx y el certbot (la herramienta de la EFF para la gestión de certificados Let’s Encrypt).

snap install core && snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot

Antes de que se nos olvide, y para que el sistema actualice y renueve los certificados cuando toque, podemos configurar un cron que lo haga.

crontab -e

Al que le diremos, por ejemplo, que actualice los certificados cada día a las 06:45.

45 6 * * * certbot renew

Configuración de nginx

Obviando la configuración de nginx, vamos a centrarnos en la configuración concreta del sitio por defecto.

cd /etc/nginx/sites-available/
vim default

Allí dejaremos algo tan sencillo como esto:

server {
  listen 80;
  listen [::]:80;
  server_name www.example.com example.com;
  root /var/www/html;
  index index.html;
  location / {
    try_files $uri $uri/ =404;
  }   
}

En esta configuración indicaremos el dominio a utilizar, que es lo principal que necesitaremos. Con esto, nuestra web debería funcionar y verse correctamente (aunque sea un simple HTML).

Comprobaremos, reiniciaremos y validaremos que nginx funciona.

nginx -t
systemctl restart nginx.service
systemctl status nginx.service

Creando el certificado

Para poder utilizar un certificado de Let’s Encrypt primero deberemos registrarnos o actualizar nuestra cuenta.

certbot register --email my_email@example.com --agree-tos --no-eff-email

Y si ya has utilizado esto previamente, puedes actualizar los datos.

certbot update_account --email my_email@example.com --agree-tos --no-eff-email

Una vez tengamos la cuenta creada, podremos crear nuestro certificado. El sistema que vamos a usar es el de la validación por DNS, que, de entre todas las posibles, es la más difícil que se vea comprometida.

certbot certonly --manual --preferred-challenges dns -d example.com -d www.example.com --cert-name example.com

En el proceso, nos pedirá que añadamos (por primera y única vez) una entrada en las DNS, de forma que sea capaz de validar que somos los propietarios del dominio.

Please deploy a DNS TXT record under the name:

_acme-challenge.example.com.

with the following value:

77cm8TbWavyWrTp2cB9zSbHL5q8x5nFqufEpS9ykQsKNwrGc

Añadiremos la entrada en las DNS y pulsaremos en continuar. Una vez hecho esto nos dará la ruta del sistema en el que se encuentra nuestro certificado.

/etc/letsencrypt/live/example.com/fullchain.pem

Instalando el certificado

Ahora que tenemos el certificado creado ya podemos instalarlo y ponerlo en funcionamiento.

Volveremos a cargar el fichero de configuración de nginx y añadiremos la parte que haga que funcione el HTTPS y que tenga activado el certificado.

cd /etc/nginx/sites-available/
vim default

Separaremos la parte sin certificado (que hará redirección del HTTP al HTTPS) y activaremos el resto.

#Mandamos todo el tráfico de HTTP a HTTP
server {
  listen 80;
  listen [::]:80;
  server_name www.example.com example.com;
  return 301 https://www.example.com$request_uri;
  access_log off;
}
#Activamos el sitio con HTTPS
server {
  listen 443 ssl;
  listen [::]:443 ssl ipv6only=on;
  server_name www.example.com example.com;
  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
  ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
  include /etc/letsencrypt/options-ssl-nginx.conf;
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
  root /var/www/html;
  index index.html;
  location / {
    try_files $uri $uri/ =404;
  }
}

Por defecto Let’s Encrypt sólo usa TLSv1.2 y TLSv1.3, que son las dos versiones correctas. En cualquier caso, deberemos asegurarnos de que eso sea así.

vim /etc/letsencrypt/options-ssl-nginx.conf

Y validaremos que en la línea correspondiente sólo está esa configuración.

ssl_protocols TLSv1.2 TLSv1.3;

Una vez esto esté configurado, validaremos y reiniciaremos nginx.

nginx -t
systemctl restart nginx.service
systemctl status nginx.service

Para validar que el certificado TLS está instalado y funcionando, podemos usar la herramienta de SSLLabs.

Esto está bien… pero ¿podemos conseguir mejor puntuación?

Validando las DNS

Si queremos que un certificado tenga cierta importancia, podemos bloquear qué proveedor lo va a emitir, algo que aumentaría la seguridad, ya que no cualquiera podría generarlo.

En este caso, podemos limitarlo por DNS (todos los proveedores tienen su configuración, y se pueden indicar varias, por prioridad).

letsencrypt.wpdanger.systems.    CAA 0 issue "letsencrypt.org"
letsencrypt.wpdanger.systems.    CAA 0 iodef "mailto:my_email@example.com"
Con esto conseguiremos un paso más.

Ampliando la seguridad

Hasta este momento tenemos un certificado seguro, pero podemos seguir aumentando ciertos parámetros.

El primero de ellos va a ser disponer de un certificado de 4096 bits en vez de uno de 2048 bits, que es el que se genera por defecto.

certbot certonly --manual --preferred-challenges dns --key-type rsa --rsa-key-size 4096 -d example.com -d www.example.com --cert-name example.com --force-renew

Y lo siguiente va a ser mejorar la configuración de nginx para activar dos elementos: el OCSP y las cabeceras de seguridad.

cd /etc/nginx/sites-available/
vim default

En el que sustituiremos la configuración.

#Mandamos todo el tráfico de HTTP a HTTP
server {
  listen 80;
  listen [::]:80;
  server_name www.example.com example.com;
  return 301 https://www.example.com$request_uri;
  access_log off;
}
#Activamos el sitio con HTTPS
server {
  listen 443 ssl;
  listen [::]:443 ssl ipv6only=on;
  server_name www.example.com example.com;

  # TLS CERT
  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
  ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
  include /etc/letsencrypt/options-ssl-nginx.conf;
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

  # TLS OCSP Stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 208.67.222.222 8.8.8.8 valid=300s;
  resolver_timeout 2s;

  # Security headers
  add_header Referrer-Policy "strict-origin-when-cross-origin" always;
  add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
  add_header X-Frame-Options SAMEORIGIN;
  add_header X-Content-Type-Options nosniff;
  add_header X-XSS-Protection "1; mode=block";

  # SITE
  root /var/www/html;
  index index.html;
  location / {
    try_files $uri $uri/ =404;
  }
}

Ahora que tenemos el nuevo certificado y la configuración, reiniciaremos el servicio.

nginx -t
systemctl restart nginx.service
systemctl status nginx.service

Y conseguiremos una puntuación y seguridad mayor.


Sobre este documento

Este documento está regulado por la licencia EUPL v1.2, publicado en WP SysAdmin y creado por Javier Casares. Por favor, si utilizas este contenido en tu sitio web, tu presentación o cualquier material que distribuyas, recuerda hacer una mención a este sitio o a su autor, y teniendo que poner el material que crees bajo licencia EUPL.