EN CONSTRUCCIÓN!!!
Curso : 202122
Area : Sistemas operativos, automatización, devops
Requisitos : Docker, docker compose, Nginx, Let's Encrypt
Tiempo : 1 sesión
Descripción : Gestionar varios contenedores con conexiones HTTPS
Enlaces de interés:
El objetivo es usar docker-compose para:
- Lanzar contenedor con un servidor web que responde a las conexiones HTTPS (nginx).
- Donde el certificado se obtendrá de otro contenedor (letsencrypt).
docker-compose.yaml
version: '3'
services:
nginx:
image: nginx:1.15-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./data/nginx:/etc/nginx/conf.d
certbot:
image: certbot/certbot
data/nginx/app.conf
A continuación, la configuración de Nginx para redirigir las peticiones HTTPS.
server {
listen 80;
server_name SERVERNAME; location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name SERVERNAME;
location / {
proxy_pass http://SERVERNAME;
}
}
- Personalizar SERVERNAME con el nombre de dominio de nuestro servidor.
WARNING: Todavía no podemos ejecutar
docker-compose up
porque el servidor Nginx todavía no tiene el certificado. Así que seguimos...
Let’s Encrypt lleva a cabo la validación del dominio de la siguiente forma:
- Certbot escribe unos datos en el URL "well-known" del servidor.
- Let's Encrypt mediante consulta al URL "well-known" del dominio lee los datos.
- Si la respuesta recibida responde correctamente, entonces se considera el dominio validado.
Vamos a necesitar los siguientes volúmenes:
- Uno para la validación.
- Y otro para los certificados.
- Modificar el fichero docker-compose.yaml, y añadir la siguiente configuración de volúmenes para los contenedores:
# Volúmenes para nginx:
volumes:
- ./data/nginx:/etc/nginx/conf.d
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
# Volúmenes para certbot:
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
En el fichero de configuración del servidor web (nginx) permitimos el acceso a la carpeta donde se guardarán los datos de respuesta para validar el dominio, en la sección server-port-80.
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
Añadimos las referencias a los certificados HTTPS en la sección server-port-443 del fichero de configuración del servidor web (nginx):
ssl_certificate /etc/letsencrypt/live/NAMESERVER/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/NAMESERVER/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
Necesitamos Nginx para ejecutar la validación de Let's Encrypt y obtener los certificados, pero Nginx no se puede ejecutar porque no tiene los certificados.
Para resolver este problema:
- Se crean unos certificados temporales
- Se inicia Nginx
- Se borran los certificados temporales
- Se solicita el certificado real
Podemos realizar todos estos pasos manualmente o usar un script que nos lo hago por nosotros de forma automática.
- Descargar el script
curl -L https://raw.githubusercontent.com/wmnnd/nginx-certbot/master/init-letsencrypt.sh > init-letsencrypt.sh
- Editar el script y modificar los nombres de dominio y cuenta de correo.
chmod +x init-letsencrypt.sh
sudo ./init-letsencrypt.sh
- Iniciar los contenedores con docker compose.
- Comprobar que funciona correctamente la conexión HTTPS.
Los certificados caducarán y entonces tendremos que volver a repetir el proceso. ¿Podríamos automatizar el proceso de renovación antes de que se caduque?
- Añadiremos lo siguiente a la sección del
certbot
dentro del docker-compose.yaml, para que el certificado se renueve automáticamente cada 12 horas:
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
- En la sección
nginx
, nos aseguraremos que se recarga la configuración y los certificados cada 6 horas en background y se lanza el servidor Nginx en foreground.
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
- Comprobamos que funciona correctamente.