How to best implement use of LE certs by other modules/daemons?
Created by: JoKeyser
I'd like to implement the use of Let's Encrypt certificates by other modules (ejabberd, mumble, etc.), but I'd like to first agree on the best approach. I mainly mean agreement among 2-3 people from @freedombox/reviewers (but any other voice also welcome). My main question is how to best make the LE cert(s) readable by other modules.
In !919 (closed) we've merged the support of ejabberd, but with hindsight I doubt that it's the most elegant way. Specifically, the ejabberd module creates a new file containing the cert and private key in a new directory, /etc/ejabberd/letsencrypt/
. That pattern strikes me as messy when more modules are added; it seems unnecessary to have as many copies as there are modules that use the LE cert.
Instead, it seems much cleaner to me if all LE-compatible modules could read the LE archive directory that contains the certificates and private key (/etc/letsencrypt/archive/$domain/
). For modules like ejabberd that require non-standard file formats, the necessary files could be (re-)created within the archive dir (e.g. using just a single post- or renew-hook script). To change a module's use of the LE certs, its access rights are added/dropped, but no files are created/copied around elsewhere than certbot's archive directory.
My question: Maybe that approach would violate some technical/security/Debian policy issue? Or am I overlooking something else?
Edit: I'll describe the problem(s) and solution candidates below in the first post, to keep it readable.
The default permissions
The relevant directory is /etc/letsencrypt/archive/$DOMAIN_NAME
, containing cert files and private keys, with a running number N=1, 2, 3, ..., e.g. privkey1.pem
.
The archive
directory is only readable by root
, preventing (read-)access from any module/service/daemon that does not start as that user.
root@freedombox:/etc/letsencrypt# tree -p .
|-- [drwx------] archive
| `-- [drwxr-xr-x] $DOMAIN_NAME
| |-- [-rw-r--r--] cert1.pem
| |-- [-rw-r--r--] chain1.pem
| |-- [-rw-r--r--] fullchain1.pem
| `-- [-rw-r--r--] privkey1.pem
|-- [drwx------] live
| |-- [drwxr-xr-x] $DOMAIN_NAME
| | |-- [-rw-r--r--] README
| | |-- [lrwxrwxrwx] cert.pem -> ../../archive/$DOMAIN_NAME/cert1.pem
| | |-- [lrwxrwxrwx] chain.pem -> ../../archive/$DOMAIN_NAME/chain1.pem
| | |-- [lrwxrwxrwx] fullchain.pem -> ../../archive/$DOMAIN_NAME/fullchain1.pem
| | `-- [lrwxrwxrwx] privkey.pem -> ../../archive/$DOMAIN_NAME/privkey1.pem
Considered candidate solutions (WIP)
- Set
archive
as readable for system groupssl-cert
, and add the modules' users to this group.- Pro: Seems a common approach, simple.
- Con: Requires package
ssl-cert
. Note there may exist daemons that don't tolerate group-readability (TODO: Are there?), thus requiring file copies again, so this option would be out.
- Set
archive
as readable for each module with Access Control Lists (ACL).- Pro: Fine-grained permissions on a per-user basis, even for daemons that insist on files that are only readable "to them" (TODO: Check if true...). That would mean no file copies are ever necessary.
- Con: Requires package
acl
. Requires filesystem that supports ACL (but that seems really common in Debian, see below).
- Copying the private key (and maybe cert) to each daemon's own directory.
- Pro: Guaranteed to work for all cases.
- Con: Multiple copies of the keys seems messy.
The ACL option appears currently more elegant to me, but more investigations are needed.