1. El propósito
Utilizar los certificados Let's Encrypt con Exim, Dovecot ... o cualquier otro servidor que realice comunicaciones mediante SSL.
2. La situación
Obviamente, se trata de indicar al servidor de que se trate que use como certificado aquel obtenido mediante certbot vigente en cada momento, es decir, el que se ubica en /etc/letsencrypt/live/{dominio}/fullchain.pem y su correspondiente clave privada /etc/letsencrypt/live/{dominio}/privkey.pem[1].
Sin embargo, eso no es tan sencillo, debido a los permisos de los directorios y ficheros implicados. Exim, por ejemplo, no lee los certificados como root, sino como usuario sin privilegios, y los directorios y ficheros implicados son propiedad de usuario y grupo root. Dado que el caso de Exim puede ser extrapolado a otros servicios, la solución que se plantee debería ser aplicable también a ellos.
3. La solución.
La solución propuesta es la creación de un grupo específico para quienes deban tener acceso de lectura a certificado y clave y el cambio de los permisos necesarios en directorios y ficheros implicados.
La dificultad aquí la plantea la renovación de los certificados. Let's Encrypt impone una frecuencia alta de renovación de certificados (como medida de seguridad y gracias al mecanismo totalmente automatizado de renovación), y cada vez que se renueva un certificado, los nuevos ficheros vuelven a pertenecer al grupo root. Y cada vez que eso ocurre, es necesario señalizarlo a los servidores que los usan. En el caso del servidor HTTP no es necesario nada especial, se encarga certbot, pero en el resto de los casos existe el problema.
Así pues, la solución exige, por un lado una serie de operaciones a realizar una sola vez y, por otro, las que han de realizarse cada vez que se renueva el certificado. Esto último se consigue mediante el uso de la opción --renew-hook en la ejecución de certbot.
4. La implementación
4.1. Operaciones iniciales
Las siguientes instrucciones tratan de ser lo mas genéricas posible, pero inevitablemente en algún momento hacen referencia a valores específicos del sistema debian.
Por un lado, se crea el nuevo grupo, se añade al mismo el usuario bajo el que corre Exim, se cambia el grupo a todo el árbol /etc/letsencrypt/ y los permisos a los ficheros y directorios implicados[2].
# crea el nuevo grupo sudo addgroup lets-extended añade el usuario bajo el que corre Exim a dicho grupo sudo usermod -a -G lets-extended Debian-exim # cambia el grupo a todo el árbol letsencrypt sudo chown -R root:lets-extended /etc/letsencrypt # cambia permisos de grupo a las ramas y ficheros de interés sudo chmod g+rx /etc/letsencrypt sudo chmod g+rx /etc/letsencrypt/archive sudo chmod g+rx /etc/letsencrypt/archive/{domain} sudo chmod g+r /etc/letsencrypt/archive/{domain}/* sudo chmod g+rx /etc/letsencrypt/live sudo chmod g+rx /etc/letsencrypt/live/{domain}
Por otro, se le indica a Exim la ubicación de certificado y clave. Por ejemplo, en debian, en /etc/exim4/exim.conf.localvariables se especifica lo siguiente:
MAIN_TLS_CERTIFICATE=/etc/letsencrypt/live/{domain}/fullchain.pem MAIN_TLS_PRIVATEKEY=/etc/letsencrypt/live/{domain}/privkey.pem
En el caso de Dovecot, tb en debian, en /etc/dovecot/local.conf, se pondría:
ssl = required ssl_cert = /etc/letsencrypt/live/{domain}/fullchain.pem ssl_key = /etc/letsencrypt/live/{domain}/privkey.pem
4.2. Operaciones a la renovación
Aquí es necesario elaborar un guión shell que corrija los permisos y grupos de los nuevos ficheros.
!/bin/sh chmod g+r /etc/letsencrypt/archive/*/fullchain*.pem chmod g+r /etc/letsencrypt/archive/*/privkey*.pem chown root:lets-extended /etc/letsencrypt/archive/*/fullchain*.pem chown root:lets-extended /etc/letsencrypt/archive/*/privkey*.pem service exim4 reload service dovecot reload
Para probarlo, se puede forzar una renovación:
sudo certbot renew --cert-name {domain} --force-renewal --renew-hook /usr/local/bin/certbot-post-renew
Y una vez comprobado, al comando del cron que ejecuta certbot para renovaciones ha de añadirsele la opción --renew-hook /usr/local/bin/certbot-post-renew. Lo que puede tener que hacerse en /lib/systemd/system/certbot.service o en la zona crontab de /etc.