Certificados gratis con Let’s Encrypt
Obtener certificados de Let’s Encrypt es relativamente sencillo. Usando el cliente certbot se puede hacer de varias formas. Explicaré una de ellas para la que hace falta disponer de un servidor Web configurado previamente, este requisito no es necesario si se usan otros métodos de los que dispone certbot.
Requisitos
- Servidor Web NGINX
Configuración de los vitualhosts
Se pueden pedir los certificados con validez para un único DNS, de forma que tendremos tantos certificados como virtualhosts tengamos en nuestro servidor web, sin embargo, yo he configurado mis virtualhosts de Nginx para usar 1 único certificado para todos ellos. Let’s Encrypt permite tener hasta 10 nombres de hosts en un único certificado (esto lo lei en algún sitio de la web de Let’s Encrypt pero no lo he vuelto a encontrar).
Primero empezaré por poner los 2 ficheros include con las opciones necesarias para este proceso.
/etc/nginx/includes/httpoptions.conf
Para los virtualhosts que usan SSL esta zona de directivas lo que hace es:
- Establece el directorio principal en /var/www/html.
- El funcionamiento de Let’s Encrypt precisa de un directorio oculto llamado .well-known que es donde se crea a su vez un subdirectorio llamado acme-challenge para poner de forma temporal una APIKEY. Esta es una de las formas que tiene Let’s Encrypt para certificar la validez de nuestra petición de certificado.
- Si en la petición que hace el cliente web NO está la cadena .well-known, entonces redirige hacia https. Esto lo he puesto para que solo en caso contrario se permanezca en el modo inseguro que necesita Let’s Encrypt.
- Por último activo la característica de navegación de archivos para el directorio .well-known. De otra forma Let’s Encrypt no podría acceder al fichero APIKEY que crea certbot. Muy fácil, ¿no?.
Todo esto se añadirá a cada virtualhost para el que se vaya a pedir un certificado.
listen 80; if ($request_uri !~* \.well-known.*) { return 301 https://$server_name$request_uri; } location ~ /\.well-known.*$ { root /var/www/html; }
/etc/nginx/includes/ssl.conf
Este fichero contiene lo necesario para que funcione el virtualhost en modo cifrado. La intención de este post es pedir un único certificado para todos mis virtualhost, así puedo separar en un fichero a parte todas las opciones de SSL y los ficheros de los virtualhost quedan mucho más legibles.
listen 443; ssl on; ssl_certificate /etc/letsencrypt/live/www.alcocer.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.alcocer.net/privkey.pem; proxy_redirect off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; ssl_dhparam /etc/nginx/dhparam.pem; if ($request_uri ~* \.well-known.*) { return 403; }
Definición de un virtualhost
Como ejemplo voy a poner 2 virtualhosts para los que voy a pedir el certificado
Virtualhost de proxmox
server { server_name proxmox.alcocer.net; include /etc/nginx/includes/httpoptions.conf; } server { server_name proxmox.alcocer.net; include /etc/nginx/includes/ssl.conf; access_log /var/log/nginx/proxmox.access.log; error_log /var/log/nginx/proxmox.error.log; location / { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass https://10.0.0.2:8006; } }
Virtualhost de amule
server { server_name amule.alcocer.net; include /etc/nginx/includes/httpoptions.conf; } server { server_name amule.alcocer.net; include /etc/nginx/includes/ssl.conf; access_log /var/log/nginx/amule.access.log; error_log /var/log/nginx/amule.error.log; location / { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://10.0.0.1:4711; } }
Comando certbot
Después de instalar certbot (viene en los repos backports de jessie) el comando es muy sencillo:
certbot certonly --webroot -w /var/www/html/ -d proxmox.alcocer.net -d amule.alcocer.net
Tan solo hay que decirle dónde va a estar el directorio .well-known y luego cada host para el que queremos pedir el certificado.
Si todo está correcto el certificado pedido estará almacenado en /etc/letsencrypt/live/dominio.
Servicio de systemd
La validez de los certificados es de 90 días así que hay que hacer un temporizador que compruebe los certificados periódicamente y los renueve cuando sea necesario de forma automática.
/etc/systemd/system/letsencrypt.timer
El temporizador se ejecutará todos los días a las 3 de la madrugada.
[Unit] Description=Renew certs from Let's Encrypt [Timer] OnCalendar=*-*-* 03:00:00 [Install] WantedBy=multi-user.target
/etc/systemd/system/letsencrypt.service
[Unit] Description=Renew certs from Let's Encrypt [Service] User=root Type=simple ExecStart=/usr/bin/certbot renew [Install] WantedBy=multi-user.target
Prueba del temporizador
Una vez activado el temporizador se puede comprobar su estado. Se ve perfectamente que se disparará a las 3 de la madrugada.
root@servidor:/etc/systemd/system# systemctl list-timers NEXT LEFT LAST PASSED UNIT ACTIVATES Sun 2017-03-12 11:35:00 CET 4s left Sun 2017-03-12 11:30:01 CET 4min 54s ago updateddns.timer updateddns.service Sun 2017-03-12 12:00:00 CET 25min left Sun 2017-03-12 00:00:01 CET 11h ago certbot.timer certbot.service Sun 2017-03-12 22:03:31 CET 10h left Sat 2017-03-11 22:03:31 CET 13h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service Mon 2017-03-13 03:00:00 CET 15h left n/a n/a letsencrypt.timer letsencrypt.service 4 timers listed. Pass --all to see loaded but inactive timers, too. root@servidor:/etc/systemd/system#
Prueba del servicio
Después de lanzar manualmente el servicio se comprueba que está correcto.
oot@servidor:/etc/systemd/system# systemctl start letsencrypt.service root@servidor:/etc/systemd/system# systemctl status letsencrypt.service ● letsencrypt.service - Renew certs from Let's Encrypt Loaded: loaded (/etc/systemd/system/letsencrypt.service; disabled) Active: inactive (dead) since Sun 2017-03-12 11:36:14 CET; 2s ago Process: 29574 ExecStart=/usr/bin/certbot renew (code=exited, status=0/SUCCESS) Main PID: 29574 (code=exited, status=0/SUCCESS) Mar 12 11:36:13 servidor systemd[1]: Started Renew certs from Let's Encrypt. Mar 12 11:36:14 servidor certbot[29574]: Saving debug log to /var/log/letsencrypt/letsencrypt.log Mar 12 11:36:14 servidor certbot[29574]: Cert not yet due for renewal Mar 12 11:36:14 servidor certbot[29574]: ------------------------------------------------------------------------------- Mar 12 11:36:14 servidor certbot[29574]: Processing /etc/letsencrypt/renewal/www.alcocer.net.conf Mar 12 11:36:14 servidor certbot[29574]: ------------------------------------------------------------------------------- Mar 12 11:36:14 servidor certbot[29574]: The following certs are not due for renewal yet: Mar 12 11:36:14 servidor certbot[29574]: /etc/letsencrypt/live/www.alcocer.net/fullchain.pem (skipped) Mar 12 11:36:14 servidor certbot[29574]: No renewals were attempted. root@servidor:/etc/systemd/system#
Vídeo de funcionamiento
1 respuesta
[…] Certificados gratis con Let’s Encrypt […]