How to use Certbot for setting up letsencrypt certificates behind a reverse proxy
Getting the official "certbot, opens an external URL in a new window" client for Letsencrypt, opens an external URL in a new window to run on a host that is not directly reachable via HTTP and/or HTTPS is a bit tricky. One specific example where this makes sense is a virtual machine that compartmentalizes some services such as mail (SMTP, IMAP) or real-time communication (XMPP, MQTT, SIP, etc.) and does intentionally not host the associated HTTP server in the same VM. There are multiple options to get Letsencrypt certificates set up on such a host, including to run the certbot client on the actual web server and then copying over the created private keys and certificates. However, this option assumes a strong trust relationships between the VMs, which we try to avoid for abvious security reasons (if the web server is successfully attacked and is configured to be able to ssh into other services for automatic certificate renewal, then the compartmentalization suddenly doesn't make much sense any more). We therefore want to execute the certbot client on the host that will actually use the certificate.
In the following, we assume a setup similar to this:
The quickest way to allow certbot to execute on VM "mail" (including renewal) is to:
ProxyPass /.well-known/acme-challenge/ http://192.168.1.70/.well-known/acme-challenge/, opens an external URL in a new window
ProxyPassReverse /.well-known/acme-challenge/ http://192.168.1.70/.well-known/acme-challenge/, opens an external URL in a new window
Make sure to include all host aliases that the SMTP/IMAP certificate should be valid for.
Note 1: The list of hostnames forwarded by the HTTP virtual host needs to include at least those passed to the certbot client.
Note 2: If multiple VMs use the same method, they can all use different certbot accounts. It is not necessary to copy the contents of /etc/letsencrypt/accounts between them.
Note 3: If non-root daemons should be able to access the TLS certificates and private keys created by certbot, it is necessary to change their permissions:
chmod +x -R /etc/letsencrypt/live /etc/letsencrypt/archive
Note 4: To automatically restart services that use these certificates after a renewal, you can use a small helper script in /etc/cron.daily/local-restart-services-on-certificate-renewal:#!/bin/sh
for s in $SERVICES; do
starttime=`systemctl -a status $s | sed -nr 's/.*Active: active \(running\) since (.*); .*/\1/p'`
reloadfiles=`find /etc/letsencrypt/live/ -newermt "$starttime"`
[ -n "$reloadfiles" ] && systemctl restart $s || true
Just add all services that reference these certificates (assuming they are managed by systemd).
That should be it. Enjoy auto-renewed certificates for hosts not directly reachable via HTTP or HTTPS.
September 17, 2017