Configuración de HTTPS con Let's Encrypt SSL Certificate para Nginx en RHEL/CentOS 7/6


Siguiendo la serie Let's Encrypt anterior con respecto al servidor web Apache o Nginx con módulo SSL/TLS, este artículo lo guiaremos sobre cómo generar e instalar un certificado SSL/TLS obtenido de forma gratuita de Let's Encrypt Certificate Authority que usaremos para asegurar las transacciones HTTP del servidor web Nginx en CentOS/RHEL 7/6 y la distribución de Fedora.

Si está buscando instalar Let's Encrypt for Apache en distribuciones RHEL/CentOS 7/6 y Fedora, siga esta guía a continuación:

  1. Un nombre de dominio registrado con registros A DNS válidos para apuntar a la dirección IP pública del servidor.
  2. Servidor web Nginx instalado con SSL habilitado y hosts virtuales habilitados (solo para alojamiento de varios dominios o subdominios).

Paso 1: Instale el servidor web Nginx

1. En el primer paso, en caso de que no tenga el demonio Nginx ya instalado, emita los siguientes comandos con privilegios de root para instalar el servidor web Nginx desde los repositorios de Epel:

# yum install epel-release
# yum install nginx

Paso 2: Descargue o clone el certificado SSL gratuito Let's Encrypt

2. El método más rápido para instalar el cliente Let’s Encrypt en sistemas Linux mediante la clonación de los paquetes de los repositorios de github.

Primero, instale el cliente git en el sistema con el siguiente comando:

# yum install git

3. Una vez que se haya instalado el cliente git, cambie el directorio a la ruta /opt y extraiga el software Let's Encrypt ejecutando los siguientes comandos:

# cd /opt
# git clone https://github.com/letsencrypt/letsencrypt

Paso 3: Genere un certificado SSL gratuito Let's Encrypt para Nginx

4. El proceso de obtención de un certificado SSL/TLS gratuito para Nginx se realizará manualmente mediante el complemento Let’s Encrypt Standalone.

Este método requiere que el puerto 80 esté libre durante el tiempo que el cliente Let's Encrypt valida la identidad del servidor y genera certificados.

Entonces, si Nginx ya se está ejecutando, detenga el demonio con el siguiente comando y ejecute la utilidad ss para confirmar que el puerto 80 ya no está en uso en la pila de red.

# service nginx stop
# systemctl stop nginx
# ss -tln

5. Ha llegado el momento de obtener un certificado SSL gratuito de Let's Encrypt. Vaya al directorio de instalación de Let's Encrypt, si aún no está allí, y ejecute el comando letsencrypt-auto con la opción certonly --standalone y -d marca para cada dominio o subdominio que desee generar un certificado como se sugiere en el siguiente ejemplo.

# cd /opt
# ./letsencrypt-auto certonly --standalone -d your_domain.tld -d www.yourdomain.tld

6. Después de que se instalen una serie de paquetes y dependencias en su máquina, Let’s Encrypt le pedirá que ingrese su cuenta que se utilizará para la recuperación de claves perdidas o notificaciones urgentes.

7. A continuación, debe aceptar los términos de la licencia presionando la tecla Intro.

8. Finalmente, si todo salió como debería, se mostrará un mensaje de información de felicitación en su terminal bash. El mensaje también se mostrará cuando el certificado caduque.

Paso 4: Instale Let's Encrypt SSL Certificate en Nginx

9. Ahora que posee un certificado SSL/TLS gratuito, es hora de instalarlo en el servidor web Nginx para que su dominio lo use.

Todos los nuevos certificados SSL se colocan en /etc/letsencrypt/live/ en un directorio que lleva el nombre de su nombre de dominio. Utilice el comando ls para enumerar los archivos de certificado emitidos para su dominio e identificarlos.

# sudo ls /etc/letsencrypt/live/
# sudo ls -al /etc/letsencrypt/live/your_domain.tld

10. Para instalar los archivos de certificado en Nginx y habilitar SSL, abra el archivo /etc/nginx/nginx.conf para editar y agregue las siguientes declaraciones después de la última línea de escucha del bloque del servidor. Utilice la siguiente ilustración como guía.

# vi /etc/nginx/nginx.conf

Extracto del bloque SSL de Nginx:

# SSL configuration
listen 443 ssl default_server;
ssl_certificate /etc/letsencrypt/live/your_domain.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain.tld/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

Reemplace la cadena del nombre de dominio de los certificados SSL para que coincida con su propio dominio.

11. Finalmente, reinicie el servicio Nginx y visite su dominio a través del protocolo HTTPS en https:/yourdomain . La página debería cargarse sin problemas, sin ningún error de certificado.

# systemctl restart nginx
# service nginx restart

12. Para verificar el certificado SSL/TLS y su rectitud visite el siguiente enlace:

https://www.ssllabs.com/ssltest/analyze.html 

13. En caso de que reciba una notificación de que su servidor admite un intercambio de claves DH débil y una calificación general de grado B, genere un nuevo cifrado Diffie-Hellman en el directorio/etc/nginx/ssl/para proteger su servidor contra el ataque Logjam por ejecutando los siguientes comandos.

# mkdir /etc/nginx/ssl
# cd /etc/nginx/ssl
# openssl dhparam -out dhparams.pem 4096

En este ejemplo, hemos utilizado una clave de 4096 bits, que en realidad tarda mucho en generarse y supone una sobrecarga adicional en su servidor y en el protocolo de enlace SSL.

En caso de que no exista una necesidad explícita de usar una clave tan larga y no sea paranoico, debería estar seguro con una clave de 2048 bits.

14. Una vez que se haya generado la clave DH, abra el archivo de configuración de Nginx y agregue las siguientes declaraciones después de la línea ssl_ciphers para agregar la clave DH y aumentar el nivel de seguridad de su dominio a un A + grado.

# vi /etc/nginx/nginx.conf

Agregue el siguiente extracto del bloque a Nginx.conf:

ssl_dhparam /etc/nginx/ssl/dhparams.pem;
ssl_session_timeout 30m;
ssl_session_cache shared:SSL:10m;
ssl_buffer_size 8k;
add_header Strict-Transport-Security max-age=31536000;

15. Reinicie el servicio Nginx para aplicar los cambios y vuelva a probar su certificado SSL borrando la caché de resultados anterior del enlace mencionado anteriormente.

# systemctl restart nginx
# service nginx restart

Paso 5: la renovación automática de Nginx gratis permite cifrar certificados SSL

16. Let's Encrypt CA publica certificados SSL/TLS gratuitos válidos por 90 días. Los certificados se pueden renovar y aplicar manualmente antes de su vencimiento utilizando el complemento webroot, sin detener su servidor web, emitiendo los siguientes comandos:

# ./letsencrypt-auto certonly -a webroot --agree-tos --renew-by-default --webroot-path=/usr/share/nginx/html/ -d yourdomain.tld -d www.yourdomain.tld
# systemctl reload nginx

Cuando ejecute el comando anterior, asegúrese de reemplazar webroot-path para que coincida con la raíz del documento del servidor web, especificada por la declaración raíz de Nginx.

17. Para renovar automáticamente el certificado antes de que expire, cree este script bash desde github erikaheidi en el directorio/usr/local/bin/y agregue el contenido a continuación (el script está ligeramente modificado para reflejar la configuración de Nginx).

# vi /usr/local/bin/cert-renew

Agregue las siguientes líneas al archivo cert-renew .

#!/bin/bash

webpath='/usr/share/nginx/html/'
domain=$1
le_path='/opt/letsencrypt'
le_conf='/etc/letsencrypt'
exp_limit=30;

get_domain_list(){
        certdomain=$1
        config_file="$le_conf/renewal/$certdomain.conf"

        if [ ! -f $config_file ] ; then
                echo "[ERROR] The config file for the certificate $certdomain was not found."
                exit 1;
        fi

        domains=$(grep --only-matching --perl-regex "(?<=domains \= ).*" "${config_file}")
        last_char=$(echo "${domains}" | awk '{print substr($0,length,1)}')

        if [ "${last_char}" = "," ]; then
                domains=$(echo "${domains}" |awk '{print substr($0, 1, length-1)}')
        fi

        echo $domains;
}

if [ -z "$domain" ] ; then
        echo "[ERROR] you must provide the domain name for the certificate renewal."
        exit 1;
fi

cert_file="/etc/letsencrypt/live/$domain/fullchain.pem"

if [ ! -f $cert_file ]; then
        echo "[ERROR] certificate file not found for domain $domain."
        exit 1;
fi

exp=$(date -d "`openssl x509 -in $cert_file -text -noout|grep "Not After"|cut -c 25-`" +%s)
datenow=$(date -d "now" +%s)
days_exp=$(echo \( $exp - $datenow \) / 86400 |bc)

echo "Checking expiration date for $domain..."

if [ "$days_exp" -gt "$exp_limit" ] ; then
        echo "The certificate is up to date, no need for renewal ($days_exp days left)."
        exit 0;
else
        echo "The certificate for $domain is about to expire soon. Starting renewal request..."
        domain_list=$( get_domain_list $domain )
"$le_path"/letsencrypt-auto certonly -a webroot --agree-tos --renew-by-default --webroot-path=”$webpath” --domains "${domain_list}"
        echo "Reloading Nginx..."
sudo systemctl reload nginx
        echo "Renewal process finished for domain $domain"
        exit 0;
fi

18. Reemplace la variable $webpath desde el principio del script para que coincida con la raíz de su documento Nginx. Asegúrese de que el script sea ejecutable y que la calculadora bc esté instalada en su sistema emitiendo los siguientes comandos.

# chmod +x /usr/local/bin/cert-renew
# yum install bc

Puede probar el script con su dominio emitiendo el siguiente comando:

# /usr/local/bin/cert-renew yourdomain.tld


19. Finalmente, para ejecutar el proceso de renovación del certificado automáticamente, agregue un nuevo trabajo cron para ejecutar el script cada semana para actualizar el certificado dentro de los 30 días antes de la fecha de vencimiento.

# crontab -e

Agregue la siguiente línea al final del archivo.

@weekly  /usr/local/bin/cert-renew your_domain.tld >> /var/log/your_domain.tld-renew.log 2>&1

¡Eso es todo! Ahora el servidor Nginx puede entregar contenido web seguro con un certificado SSL/TLS Let's Encrypt gratuito en su sitio web.