Colourful Norwich skyline illustration

Michael Sage

IT, Digital & Culture

Cloudkey 2+ Let’s Encrypt & Backups

Let's Encrypt using DNS on Cloudkey 2+ & Backups

Update: 16/02/2021 – For CK2+ off controller backups see this great how-to: https://lazyadmin.nl/home-network/backup-unifi-controller-to-cloud/

Update: 22/12/2020 – Use this script instead: https://glennr.nl/s/unifi-lets-encrypt

Stolen from the UI community site, but copied here in case Unifi change their forums again or it gets lost to the mists of time (Original URL: https://community.ui.com/questions/How-To-Lets-Encrypt-with-Cloud-Key-and-DNS-Challenge/)

Uses the domain my-domain.xyz, one shortcoming is that my current external DNS provider doesn’t have an API, so I have to manually complete the challenge every 3 months, but the whole process takes just a few minutes so I’m not too concerned.

All steps are performed directly on the Cloud Key.

First, install Git and obtain the Let’s Encrypt code:

cd /home

sudo apt-get update

sudo apt-get install git

git clone https://github.com/letsencrypt/letsencrypt

Next, generate a certificate, specifying that you want to use a DNS challenge for proving ownership of the domain.

certbot certonly --manual --preferred-challenges dns --email notification-email@my-domain.xyz --domains unifi.my-domain.xyz

In this example, unifi.my-domain.xyz is an internal hostname that resolves to my cloud key, and notification-email@my-domain.xyz is an email address where I’d like Let’s Encrypt to send me a reminder when the certificate is about to expire.

Since we are using a DNS challenge, you will be prompted to create a TXT record with your DNS provider.  Let’s Encrypt will confirm that the DNS record is visible from their cloud infrastructure, thus proving you own the domain, and it will grant your certificate.

Next, stop unifi, since we’re about to mess with its certificates:

service unifi stop

Next, make a backup of the existing certificate data and remove it:

mkdir cert_backup

cp -r /etc/ssl/private/ cert_backup

rm /etc/ssl/private/cert.tarrm /etc/ssl/private/ssl-cert-snakeoil.key

Next, export your newly-granted Let’s Encrypt certificate into a format that Unifi understands:

cd /etc/letsencrypt/live/unifi.my-domain.xyz/

openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out cert.p12 -name unifi -password pass:your_certificate_password

Here, your_certificate_password is a temporary password of your choosing to protect the exported certificate.

Next, import the Let’s Encrypt certificate into the Unifi keystore:

keytool -importkeystore -deststorepass aircontrolenterprise -destkeypass aircontrolenterprise -destkeystore /usr/lib/unifi/data/keystore -srckeystore cert.p12 -srcstoretype PKCS12 -srcstorepass your_certificate_password -alias unifi

Note that aircontrolenterprise is the Unifi keystore password; it is not a password of your choosing.

In this command, /usr/lib/unifi/data/keystore is actually a symlink pointing to the /etc/ssl/private directory from earlier.

At this point, the Unifi Controller will work with your Let’s Encrypt certificate, but recall that the Cloud Key has a separate internal nginx-based webserver to handle OS configuration options.

Next, replace the default certificates in the location nginx is expecting them, and make sure the permissions are correct:

cp fullchain.pem /etc/ssl/private/cloudkey.crt

cp privkey.pem /etc/ssl/private/cloudkey.key

chown root:ssl-cert /etc/ssl/private/*

chmod 640 /etc/ssl/private/*

tar -cvf cert.tar *

chown root:ssl-cert cert.tar

chmod 640 cert.tar

Finally, restart nginx, protect and start the Unifi controller.

service nginx restart

service unifi-protect restart

service unifi start

At this point, they should come up and be using your Let’s Encrypt certificate.

Set a calendar reminder for ~2 months from now so you don’t forget to redo this before the certificate expires!

This guide simply re-arranges the hard work that others have done into a solution that fits my specific needs.  The author (pcoldren) used bits and pieces from the following resources while writing it:

https://community.spiceworks.com/how_to/128281-use-lets-encrypt-ssl-certs-with-unifi-cloud-key

https://tom-henderson.github.io/2015/06/05/unifi-ssl.html

https://serverfault.com/questions/750902/how-to-use-lets-encrypt-dns-challenge-validation

https://www.c0ffee.net/blog/unifi-cloud-key-ssl-certificate

https://www.naschenweng.info/2017/01/06/securing-ubiquiti-unifi-cloud-key-encrypt-automatic-dns-01-challenge/