2025-09-21 21:13:00
The past few days I've been slowly piecing together a self-hosted email and productivity platform, just to see if I could. This project has a lot of moving pieces, which all need to sync up, so I don't look like a spammer to the outside world.
One of the things I need, is a properly trusted certificate. One free and easy way to get those is through Lets Encrypt. Their Certificate Authority uses a very hands-off approach, insofar that it's aimed at high automation through the Acme tooling.
With Acme there are a few ways you can prove that you're actually requesting a certificate for a domain you own. By far the easiest, is to have Acme run as a scheduled job on your public web server. If that's not an option you can also provide Acme with API access to your DNS records. And if that's not an option? Well...
As it usually goes, I'm making things more difficult than I have to.
I could use the easiest approach, running Acme with the web server for my email platform. The trouble is that this web server also offers the webmail as well as the admin functionality for the platform. I want neither of those on the web, I want them 100% in my private network only. And there's no easy way to split them.
I could also look into API access to my TransIP DNS account and in the long term I probably will. But not for now.
So I had to go the third way: the Acme manual DNS registration. This means that I need to manually run the acme.sh client, then manually register the DNS record their API expects, then rerun acme.sh to get the certificate. And I need to repeat that at least every fifty days. Here's some useful acme.sh documentation.
The process on my server was as follows. First I edited mailcow.conf to set "SKIP_LETS_ENCRYPT=y". This is per Mailcow's own documentation.
I then ran:
git clone https://github.com/acmesh-official/acme.sh.git /opt/acme.sh
echo 'export PATH="${PATH}:/opt/acme.sh"' > ~/.bashrc
chmod +x /opt/acme.sh/acme.sh
acme.sh --issue -d mail.${MyDomain} --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please
Then I went ahead and created the requested DNS record. After waiting for it to propagate, I run the following. The export/install instructions were found here.
acme.sh --set-default-ca --server https://acme-v02.api.letsencrypt.org/directory
acme.sh --issue -d mail.${MyDomain} --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please --renew
acme.sh --install-cert -d mail.${MyDomain} \
--cert-file data/assets/ssl/nochain.pem \
--key-file data/assets/ssl/key.pem \
--fullchain-file data/assets/ssl/cert.pem
docker compose restart
In the ideal case, I'd have a way of the built-in Acme registration to work without exposing the web interface(s) but the developers have already indicated they won't be building that any time soon.
kilala.nl tags: sysadmin,
View or add comments (curr. 0)
All content, with exception of "borrowed" blogpost images, or unless otherwise indicated, is copyright of Tess Sluijter. The character Kilala the cat-demon is copyright of Rumiko Takahashi and used here without permission.