En este post, mejoraremos la seguridad de nuestro site con soporte SSL partiendo de la configuración obtenida después de seguir los pasos descritos en Nginx y Let’s Encrypt.

  • Configuración inicial con el certificado obtenido de Let’s Encrypt
server {
    server_name lynks.duckdns.org;
    root /var/www/miblog/;
    location \ {
               try_files $uri $uri/ =404;
    }
    access_log /var/log/nginx/lynks.duckdns.org.access.log;

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/lynks.duckdns.org/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/lynks.duckdns.org/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = lynks.duckdns.org) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    server_name lynks.duckdns.org;
    return 404; # managed by Certbot
}
  • Configuramos nginx, para sugerir a cada visitante utilizar el protocolo HTTPS por defecto:
add_header Strict-Transport-Security "max-age=63072000" always;
  • Mediante la siguiente directiva, se indica a los clientes las versiones sportadas del protocolo TLS en nuestro servidor nginx:
ssl_protocols TLSv1.2 TLSv1.3;
  • Configuramos los tipos de cifrado disponibles e indicamos que nginx, se encargará de escoger el adecuado:
ssl_prefer_server_ciphers on;
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;
  • Indicamos la política de sesiones:
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
  • Activamos OCSP Stapling, un mecanismo para que el cliente valide la autenticidad del certificado:
ssl_stapling on;
ssl_stapling_verify on;
  • Los cifrados que utilizan el protocolo Diffie-Hellman son vulnerables, ya que usan un cifrado de 1024 bits. Para mejorar la seguridad, creamos un cifrado de 2048 bits, utilizando openssl:
$ sudo openssl dhparam -out /etc/nginx/dhparams.pem 2048
  • Configuramos nginx para que utilice dhparam:
ssl_dhparam /etc/nginx/dhparams.pem;
  • Si hemos seguido los pasos anteriores, obtendremos la siguiente configuración:
server {
    listen 443 ssl;
    server_name lynks.duckdns.org;
    root /var/www/miblog/;
    location \ {
               try_files $uri $uri/ =404;
    }
    access_log /var/log/nginx/lynks.duckdns.org.access.log;

    add_header Strict-Transport-Security "max-age=63072000" always;

    ssl_protocols TLSv1.2 TLSv1.3;

    ssl_prefer_server_ciphers on;
    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_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m;
    ssl_session_tickets off;

    ssl_stapling on;
    ssl_stapling_verify on;

    ssl_dhparam /etc/nginx/dhparams.pem;


    ssl_certificate /etc/letsencrypt/live/lynks.duckdns.org/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/lynks.duckdns.org/privkey.pem; # managed by Certbot


}
server {
    if ($host = lynks.duckdns.org) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    server_name lynks.duckdns.org;
    return 404; # managed by Certbot
}
  • Podemos verificar la seguridad actual de nuestro site, lanzando el test de SSL Labs, donde obtendremos la clasificación A.

Alt text