Let’s Encrypt, Ubuntu, Certbot and the Unifi Controller

For the sake of this post, let’s assume you’re running a quite minimal install of Ubuntu 18.05 Bionic Beaver and have installed your Unifi Controller with the script from Glenn Rietveld.

Install certbot

Follow the official instructions. They’re good. In short, it’s just the following steps:

$ sudo apt install software-properties-common
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt update
$ sudo apt install python3-certbot-nginx

Create renew-hook for the Unifi Controller

Create the script /etc/letsencrypt/renewal-hooks/deploy/import-to-unifi

#!/bin/bash

# Make sure you only have one letsencrypt cert in this server
# If you have more than one, uncomment the following line
# and adjust to your unifi controller's domain name.
#CERTBOT_DOMAIN =unifi.some.where

LE_LIVE=/etc/letsencrypt/live
UNIFI_KEYSTORE=/var/lib/unifi/keystore

if [ ${LE_LIVE}/${CERTBOT_DOMAIN}/cert.pem -nt ${UNIFI_KEYSTORE} ]; then
	WORKDIR=$(mktemp -d)
	openssl pkcs12 -export -inkey ${LE_LIVE}/${CERTBOT_DOMAIN}/privkey.pem -in ${LE_LIVE}/${CERTBOT_DOMAIN}/fullchain.pem -out ${WORKDIR}/cert.p12 -name unifi -password pass:temppass
	cp ${UNIFI_KEYSTORE} ${UNIFI_KEYSTORE}-$(date +%s)
	keytool -importkeystore -deststorepass aircontrolenterprise -destkeypass aircontrolenterprise -destkeystore ${UNIFI_KEYSTORE} -srckeystore ${WORKDIR}/cert.p12 -srcstoretype PKCS12 -srcstorepass temppass -alias unifi -noprompt
	systemctl restart unifi.service
	rm ${WORKDIR}/cert.p12
	rmdir ${WORKDIR}
fi

Run certbot the first time

$ certbot --nginx
# Answer the questions as needed

Verify everything worked

$ echo "" | openssl s_client -connect 127.0.0.1:8443
CONNECTED(00000005)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = unifi.some.where
verify return:1
---
[...]

Closing notes

This is mostly written as a reminder for myself. Hopefully it’ll help someone. 

I haven’t tested how resilient this is when for example upgrading the unifi controller. Possibly one needs to touch /etc/letsencrypt/live/${CERTBOT_DOMAIN}/cert.pem and run the hook manually after the upgrade for the cert to keep the keystore fresh. I’ve seen it happen in other places using keystores.