Aprende a proteger Nginx con Let’s Encrypt en CentOS 7

Comprobación de seguridad SSL Let's encrypt

Si necesitas un certificado SSL gratuito, aprende a proteger un servidor Nginx con Let’s Encrypt. Los certificados SSL se utilizan a menudo en portales web en los que la información debe ir encriptada para evitar problemas de seguridad. Y aunque en el mercado existe un gran número de autoridades certificadoras que proporcionan este tipo de certificados de seguridad, la mayoría son de pago. Por eso, en este artículo te mostramos cómo generar un SSL gratuito para usarlo en un servidor Nginx.

Para crearlo usaremos Let’s Encrypt que, para quién no lo conozca, es una autoridad certificadora que proporciona una manera sencilla de obtener e instalar certificados TLS/SSL gratuitos. Sigue leyendo para descubrir cómo crear tu certificado SSL.

Prerrequisitos para proteger Nginx con Let’s Encrypt

Antes de empezar con este tutorial es necesario que conozcas algunos requisitos previos.

  • Disponer de un servidor CentOS 7 con usuario root que tenga todos los privilegios.
  • Administrar el nombre del dominio sobre el que deseas utilizar el certificado.
  • Asegurarse de que la zona de DNS del dominio cuenta con un registro A, que apunte a la dirección IP pública del servidor. Esto es necesario, ya que Let’s Encrypt lo utilizará para realizar la validación.

Si cumples con estos prerrequisitios, puedes instalar el software del cliente Let’s Encrypt.

Paso 1 – Instalar el software de Let’s Encrypt

Para obtener el certificado SSL, lo primero que hay que hacer es instalar el software que nos permitirá hacer esto en nuestra máquina. La mejor forma de hacerlo es a través del repositorio EPEL. Para ello, es necesario habilitar el acceso a ese repositorio ejecutando lo siguiente:

sudo yum install epel-release

Una vez habilitado, podemos obtener el paquete escribiendo:

sudo yum install certbot

De esta forma, el cliente certbot estará instalado y listo para ser utilizado.

Paso 2 – Obtener el certificado

Let’s Encrypt ofrece varias opciones para crear el certificado a través de varios complementos. Nosotros nos centraremos en el uso del plugin Webroot.

¿Cómo utilizamos el plugin Webroot?

Este complemento funciona colocando un archivo especial en el directorio /.well-known dentro de nuestro raíz. Dependiendo de nuestra configuración, puede que sea necesario darle permisos para que Let’s Encrypt pueda acceder a él. Si Nginx no está instalado, puedes instalarlo ejecutando la siguiente instrucción:

sudo yum install nginx

Para asegurarnos de que ese directorio estará accesible para Let’s Encrypt, vamos a realizar un cambio rápido en la configuración predeterminada de Nginx. Si utilizamos la configuración predeterminada, lo que haremos será crear un archivo con el siguiente nombre: le-well-known.conf. Para editarlo, usaremos el siguiente comando:

sudo vi /etc/nginx/default.d/le-well-known.conf

A continuación, en su interior colocaremos las siguientes líneas:

location ~ /.well-known {
allow all;
}

Después, guardamos y salimos de la edición. También tenemos que comprobar que no hemos cometido ningún tipo de error en la sintaxis que hemos utilizado. Para ello ejecutamos lo siguiente:

sudo nginx -t

Si no hay ningún error, reiniciaremos el servidor Nginx con esta instrucción.

sudo systemctl restart nginx

También será necesario que nos aseguremos de que están abiertos los puertos 80 y 443. Si utilizamos un cortafuegos, podemos abrirlos ejecutando los siguientes comandos:

sudo firewall-cmd –add-service=http
sudo firewall-cmd –add-service=https
sudo firewall-cmd –runtime-to-permanent

Si, por el contrario, utilizamos IP Tables, las instrucciones que tendremos que usar dependerán de nuestras reglas actuales. En el caso de utilizar reglas básicas, estas dos instrucciones deberían ser suficientes.

sudo iptables -I INPUT -p tcp -m tcp –dport 80 -j ACCEPT
sudo iptables -I INPUT -p tcp -m tcp –dport 443 -j ACCEPT

Una vez realizados los pasos anteriores, ya podremos utilizar el plugin Webroot para solicitar el certificado SSL mediante el siguiente comando.

sudo certbot certonly -a webroot –webroot-path=/usr/share/nginx/html -d example.com -d www.example.com

Hay que utilizar la opción –d para indicar el nombre del dominio sobre el que se va a instalar el certificado. En caso de utilizar más de un dominio, hay que indicarlo de forma separada incluyendo esta opción delante de cada uno de ellos. Asimismo, hay que tener en cuenta que un dominio con y sin www es considerado diferente.

Cuando Certbot se inicie, nos pedirá una serie de datos. Esto dependerá de si ya lo hemos utilizado anteriormente o de si es la primera vez. Para mostrar todo el proceso, vamos a suponer que nunca lo hemos utilizado. De esta forma, en la primera pantalla que nos aparecerá introduciremos nuestro correo electrónico. Aquí será donde recibamos los avisos y recuperemos claves perdidas.

Introducir email en Certbot para recibir avisos y recuperar claves

Luego debemos aceptar los términos de Let’s Encrypt.

Términos y condiciones de Let's Encrypt

Si todo ha ido bien, deberíamos ver algo parecido a lo siguiente.

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
 /etc/letsencrypt/live/example.com/fullchain.pem. Your
 cert will expire on 2017-01-10. To obtain a new version of the
 certificate in the future, simply run Let's Encrypt again.
 - If you lose your account credentials, you can recover through
 e-mails sent to sammy@digitalocean.com
 - Your account credentials have been saved in your Let's Encrypt
 configuration directory at /etc/letsencrypt. You should make a
 secure backup of this folder now. This configuration directory will
 also contain certificates and private keys obtained by Let's
 Encrypt so making regular backups of this folder is ideal.
 - If like Let's Encrypt, please consider supporting our work by:

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

En el mensaje anterior podemos ver la fecha de expiración y la ruta de nuestro SSL.

Archivos del certificado

Una vez que hemos generado el certificado, deberíamos tener los siguientes archivos:

  • pem: Certificado de nuestro dominio.
  • pem: Certificado de Let’s Encrypt.
  • pem: Una combinación de los dos anteriores.
  • pem: Clave privada de nuestro certificado.

Generar un grupo fuerte Diffie-Hellman

Para aumentar aún más la seguridad también es necesario generar un grupo Diffie-Hellman fuerte. Para generar un grupo de 2048 bits hay que ejecutar los siguiente:

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Paso 3 – Configurar TLS/SSL en el servidor Nginx

El siguiente paso será editar la configuración de Nginx para usar los archivos del certificado que hemos generado con Let’s Encrypt. Para ello crearemos un nuevo bloque en el archivo de configuración en el que indicaremos que utiliza SSL/TLS y escucha en el puerto 443.

Por defecto, este nuevo bloque se puede colocar en /etc/nginx/conf.d. Para ello crearemos un nuevo archivo al que llamaremos ssl.conf. Una vez creado, lo editaremos y en su interior colocaremos el siguiente código.

server {
 listen 443 http2 ssl;

server_name example.com www.example.com;

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
 ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

########################################################################
 # from https://cipherli.st/ #
 # and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html #
 ########################################################################

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
 ssl_prefer_server_ciphers on;
 ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
 ssl_ecdh_curve secp384r1;
 ssl_session_cache shared:SSL:10m;
 ssl_session_tickets off;
 ssl_stapling on;
 ssl_stapling_verify on;
 resolver 8.8.8.8 8.8.4.4 valid=300s;
 resolver_timeout 5s;
 # Disable preloading HSTS for now. You can use the commented out header line that includes
 # the "preload" directive if you understand the implications.
 #add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
 add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
 add_header X-Frame-Options DENY;
 add_header X-Content-Type-Options nosniff;

##################################
 # END https://cipherli.st/ BLOCK #
 ##################################

ssl_dhparam /etc/ssl/certs/dhparam.pem;

location ~ /.well-known {
 allow all;
 }

# The rest of your server block
 root /usr/share/nginx/html;
 index index.html index.htm;

location / {
 # First attempt to serve request as file, then
 # as directory, then fall back to displaying a 404.
 try_files $uri $uri/ =404;
 }
}

En el código anterior, hay que cambiar el nombre del dominio example.com por el que estemos utilizando. Luego guardamos y cerramos el archivo. Lo siguiente será configurar Nginx para redirigir las peticiones HTTP del puerto 80 hacia HTTPS en el puerto 443. Recuerda que si además tienes activo HTTP2, todo irá más rápido. Para ello tendremos que crear un archivo al que llamaremos ssl-redirect.conf, dentro de la ruta /etc/nginx/default.d. Lo abriremos y en su interior pegaremos lo siguiente:

return 301 https://$host$request_uri;

Después, guardamos los cambios, salimos y comprobamos que todo está correcto:

sudo nginx -t

Y si no hay errores, reiniciamos Nginx:

sudo systemctl restart nginx

Una vez hecho todo esto, el certificado ya está activo. Solo quedaría probar que funciona correctamente. Para ello solo tenemos que visitar nuestro dominio con el protocolo HTTPS desde un navegador web.

Paso 4 – Configurar la renovación automática

Los certificados que se generan son válidos durante 90 días, pero se recomienda renovarlos cada 60 días por si ocurriera cualquier error. Renovar todos nuestros certificados es tan fácil como ejecutar lo siguiente:

sudo certbot renew

Si queremos asegurarnos de que nuestros certificados se renuevan automáticamente, lo más sencillo y cómodo es programar una cron que se ejecute cada día o cada semana. De esta forma, si hubiera algún certificado a punto de vencer, se renovaría. Si no fuera así, no pasaría nada. Para programarlo, editaremos el crontab para crear una nueva tarea que se encargue de ejecutar este comando por el usuario root:

30 2 * * 1 /usr/bin/certbot renew >> /var/log/le-renew.log 35 2 * * 1 /usr/bin/systemctl reload nginx

Para terminar, guarda los cambios y cierra el archivo. De esta forma, la orden de renovación se ejecutará todos los lunes a las 2.30 de la mañana.

Si te ha gustado, compártelo en redes sociales