Certbot + LetsEncrypt + Docker Nginx

Certbot + LetsEncrypt + Docker Nginx

Configura un certificado SSL gratuito con Certbot y Let's Encrypt en un entorno Docker Nginx. Este artículo te guía a través de los pasos necesarios para mejorar la seguridad de tu sitio web.

¿Qué es HTTPS?

HTTPS es un protocolo de aplicación basado en el protocolo HTTP, destinado a la transferencia segura de datos de Hipertexto, es decir, es la versión segura de HTTP.

¿Qué es CertBot?

Certbot es una herramienta de software gratuita y de código abierto para usar automáticamente los certificados Let’s Encrypt en sitios web administrados manualmente para habilitar HTTPS.

Certbot está hecho por la Electronic Frontier Foundation (EFF), una organización 501 (c) 3 sin fines de lucro con sede en San Francisco, California, que defiende la privacidad digital, la libertad de expresión y la innovación.

¿Qué es LetsEncrypt?

Let’s Encrypt es una autoridad de certificación gratuita, automatizada, y abierta traida a ustedes por la organización sin ánimos de lucro Internet Security Research Group (ISRG).

Prerequisitos

  1. Disponemos de una imagen docker de nginx creada con docker-compose.
  2. Tenemos un dominio registrado y activo.
  3. Tenemos acceso a la configuración de DNS del dominio.

Configuración actual de docker-compose de nginx

version: "3.3"

services:
  nginx:
    container_name: nginx
    image: nginx:latest
    volumes:
     - /srv/nginx/public_html:/usr/share/nginx/html
     - /srv/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
     - /srv/nginx/conf:/etc/nginx/conf.d
    ports:
     - "80:80"
     - "443:443"

Configurar docker-compose para usar Certbot

version: "3.3"

services:
  nginx:
    container_name: nginx
    image: nginx:latest
    volumes:
     - /srv/nginx/public_html:/usr/share/nginx/html
     - /srv/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
     - /srv/nginx/conf:/etc/nginx/conf.d
     - /srv/nginx/data/certbot/conf:/etc/letsencrypt
	  - /srv/nginx/data/certbot/www:/var/www/certbot
    ports:
     - "80:80"
     - "443:443"
  certbot:
    image: certbot/certbot
    volumes:
      - /srv/nginx/data/certbot/conf:/etc/letsencrypt
      - /srv/nginx/data/certbot/www:/var/www/certbot  

Configuración Nginx

Guardamos el siguiente fichero como data/nginx/app.conf junto al fichero docker-compose.yml.

server {
    listen 80;
    server_name jacrdeveloper.es;
    location / {
        return 301 https://$host$request_uri;
    }    
}
server {
    listen 443 ssl;
    server_name jacrdeveloper.es;
    
    location / {
        proxy_pass http://example.org; #for demo purposes
    }
}

En el fichero nginx.conf donde tengamos la configuración del dominio para https, añadimos las líneas siguientes:

ssl_certificate /etc/letsencrypt/live/jacrdeveloper.es/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/jacrdeveloper.es/privkey.pem;

En nuestro caso es jacrdeveloper.es, hay que poner en cada caso el dominio implicado. Si queremos dejar la configuración perfecta, podemos añadir:

include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

Esto nos dara una puntuación de A en SSL Labs Test

Obtener el certificado SSL

Descargamos el script init-letsencrypt.sh desde https://raw.githubusercontent.com/wmnnd/nginx-certbot/master/init-letsencrypt.sh.

curl -L https://raw.githubusercontent.com/wmnnd/nginx-certbot/master/init-letsencrypt.sh > init-letsencrypt.sh

Editamos el script y añadimos nuestro dominio y nuestra dirección de correo. En este caso jacrdeveloper.es

Damos permisos de ejecución y lo ejecutamos.

chmod +x init-letsencrypt.sh
sudo ./init-letsencrypt.sh

Si todo ha ido bien obtendremos el siguiente mensaje:

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/jacrdeveloper.es/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/jacrdeveloper.es/privkey.pem
   Your cert will expire on 2020-07-23. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - Your account credentials have been saved in your Certbot
   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 Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

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

Renovación automática de Certbot

Añadimos lo siguiente a la sección de certbot del fichero docker-compose.

entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"

En la sección de nginx añadimos:

command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"