Linux: Securizar Nginx con Let´s Encrypt en CentOS 8

Después de instalar Nginx en CentOS 8 como os explique en la anterior entrada, en esta ocasión voy a explicaros como podéis securizar vuestro Nginx mediante un certificado SSL generado por Let´s Encrypt.

Prerequisitos

  • Dominio apuntando a una IP pública de vuestra propiedad.
  • En caso de disponer de un Firewall perimetral debéis permitir conexiones al puerto 80 y 443 dirigidas al servidor donde se encuentra alojado Nginx.

Instalación de Certbot

Para poder generar nuestro certificado SSL con Let´s Encrypt en primer lugar tendremos que instalar la herramienta Certbot. Esta herramienta no se encuentra en los repositorios estándar de CentOS 8 por lo que tendremos que descargárnoslo desde su web oficial.

sudo wget -P /usr/local/bin https://dl.eff.org/certbot-auto

Convertimos el script a un fichero del tipo ejecutable.

sudo chmod +x /usr/local/bin/certbot-auto

Generación claves Diffie-Hellman

Diffie-Hellman (DH) para aquellos que no lo conozcáis es un método para generar una clave privada entre dos máquinas conectadas a través de un canal inseguro.

Vamos a generar una clave DH de 2048 bits, para ello ejecutaremos el siguiente comando:

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

Obtención del certificado Let´s Encrypt

En primer lugar crearemos los directorios que nos harán falta y le daremos acceso a Nginx.

sudo mkdir -p /var/lib/letsencrypt/.well-known
sudo chgrp nginx /var/lib/letsencrypt
sudo chmod g+s /var/lib/letsencrypt
sudo mkdir /etc/nginx/snippets

Para evitar duplicar código crearemos dos fragmentos de código los cuales incluiremos en todos los archivos de bloques del servidor Nginx.

El primer fichero lo ubicaremos en la ruta /etc/nginx/snippets/letsencrypt.conf e incluiremos el siguiente código.

location ^~ /.well-known/acme-challenge/ {
  allow all;
  root /var/lib/letsencrypt/;
  default_type "text/plain";
  try_files $uri =404;
}

El segundo fichero lo ubicaremos en la ruta /etc/nginx/snippets/ssl.conf e incluiremos el siguiente código.

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

ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 30s;

add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;

Una vez tenemos creados los 2 ficheros los incluiremos en el fichero de configuración de Nginx que podremos encontrar en la ruta /etc/nginx/conf.d/default.conf

server {
  listen 80;
  server_name www.example.com;

  include snippets/letsencrypt.conf;
}

Refrescamos la configuración de Nginx para que se apliquen los cambios.

sudo systemctl reload nginx

Ejecutamos la herramienta certbot para generar nuestro certificado SSL.

sudo /usr/local/bin/certbot-auto certonly --agree-tos --email [email protected] --webroot -w /var/lib/letsencrypt/ -d www.example.com

Si todo ha ido bien nos aparecerá una pantalla como la siguiente.

Una vez generado nuestro certificado SSL lo incluiremos en Nginx. Para ello modificaremos el fichero /etc/nginx/conf.d/default.conf tal y como indico a continuación.

Nota: Tendréis que customizar el fichero cambiando el dominio example.com por el dominio que hayáis usado así como las rutas donde hayais generado el certificado con Let´s Encrypt.

server {
    listen       80;
    server_name  localhost www.example.com;

    include snippets/letsencrypt.conf;
    return 301 https://$host$request_uri;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}
server {
    listen 443 ssl http2;
    server_name www.example.com;

    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/www.example.com/chain.pem;
    include snippets/ssl.conf;
    include snippets/letsencrypt.conf;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

Para finalizar reiniciamos el servicio de Nginx

sudo systemctl reload nginx

Y ya podremos acceder a Nginx utilizando https:// con un certificado válido.

Espero os haya servido de utilidad.

Entradas relacionadas

Deja un comentario