How to: LetsEncrypt in standalone mode for Unifi on Ubuntu 20.04 LTS
This is an update of my previous post, now that cert-manager is more mature, and i’ve rebuilt my server on Ubuntu 20.04 (from 18.04).
- install certbot
- install script to update unifi certificate
- Test
- Issue full certificate
- Install cron jobs to automate renewal
Install certbot
Certbot installation instructions are at online of course but here’s a summary:
- Update package list:
sudo apt update
- install:
sudo apt install -y certbot
Create a new certificate using LetsEncrypt
We’re going to use standalone mode, and first we’ll get a test certificate just to validate that everything’s working (so that we don’t trigger LetsEncrypt’s rate limits).
- open port 80 in ufw:
sudo ufw allow http
- Test certificate issuance:
sudo certbot certonly --standalone -d <hostname> -n --test-cert --agree-tos -m <email>
You should see something like this:
Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator standalone, Installer None Obtaining a new certificate Performing the following challenges: http-01 challenge for <hostname> Waiting for verification... Cleaning up challenges IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/<hostname>/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/<hostname>/privkey.pem Your cert will expire on 2021-04-08. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal.
- If that’s worked, close the firewall (
sudo ufw deny http
) and move on to the next step and install the certificate in unifi. Later, we’ll come back and get a ‘real’ (not staging) certificate.
Install certificate in unifi
I use an amazing certificate installation script from Steve Jenkins.
- Get the script:
wget https://raw.githubusercontent.com/stevejenkins/unifi-linux-utils/master/unifi_ssl_import.sh
- Edit the config settings in the script to add hostname, switch from Fedora/RedHat/CentOS to Debian/Ubuntu, enable
LE_MODE
, and disable key paths:
# CONFIGURATION OPTIONS UNIFI_HOSTNAME=<hostname> UNIFI_SERVICE=unifi # Uncomment following three lines for Fedora/RedHat/CentOS # UNIFI_DIR=/opt/UniFi # JAVA_DIR=${UNIFI_DIR} # KEYSTORE=${UNIFI_DIR}/data/keystore # Uncomment following three lines for Debian/Ubuntu UNIFI_DIR=/var/lib/unifi JAVA_DIR=/usr/lib/unifi KEYSTORE=${UNIFI_DIR}/keystore # Uncomment following three lines for CloudKey #UNIFI_DIR=/var/lib/unifi #JAVA_DIR=/usr/lib/unifi #KEYSTORE=${JAVA_DIR}/data/keystore # FOR LET'S ENCRYPT SSL CERTIFICATES ONLY # Generate your Let's Encrtypt key & cert with certbot before running this script LE_MODE=yes LE_LIVE_DIR=/etc/letsencrypt/live # THE FOLLOWING OPTIONS NOT REQUIRED IF LE_MODE IS ENABLED # PRIV_KEY=/etc/ssl/private/hostname.example.com.key # SIGNED_CRT=/etc/ssl/certs/hostname.example.com.crt # CHAIN_FILE=/etc/ssl/certs/startssl-chain.crt
- copy to
/usr/local/bin
and make executable:
sudo cp unifi_ssl_import.sh /usr/local/bin/ sudo chmod +x /usr/local/bin/unifi_ssl_import.sh
- Run the script to import the certificate. Look for any errors:
sudo /usr/local/bin/unifi_ssl_import.sh
- Navigate to your server (
https://<hostname>:8443
). If it worked, you’ll see a warning that the certificate isnt trusted, but when you examine the cert, it’s issued by a ‘fake’ Lets Encrypt issuer, for example:

Get the real LetsEncrypt certificate
Simply run the same certbot command as before, but leave off the --test-cert
flag, and add the --force-renew
flag to force it to replace the (unexpired) test certificate:
sudo certbot certonly --standalone -d <hostname> -n --force-renew --agree-tos -m <email>
and rerun the installation script:
sudo /usr/local/bin/unifi_ssl_import.sh
Close the browser window and reopen it, then navigate to your server again. You should now see the valid certificate:

Automate renewal and issuance
Set up a crontab to renew the cert. Pick a randomish time. It should run every day – if the certificate is still valid, it’ll just skip
- load crontab – you may be asked to pick an editor – i suggest nano:
sudo crontab -e
- add the schedule – use crontab guru if you arent familiar with crontab schedule expressions, and set up tasks to:
- request a new certificate, and
- install the updated certificate. I chose a time just over an hour after certificate issue.
It should look like this:
# renew any certificates due to expire soon at 05:20 each day 20 5 * * * /usr/bin/certbot renew --standalone -n --agree-tos -m <email> --pre-hook 'ufw allow http' --post-hook 'ufw deny http' # install any updated certificates at 06:29 each day 29 6 * * * /usr/local/bin/unifi_ssl_import.sh
The --pre-hook
and --post-hook
commands tell UFW to open up port 80 and then close it again afterwards.