eap-tls

in Wireless

Upgrade UniFi Server – A guide to SSL automation and renewal

Upgrading your UniFi Server is essential for maintaining performance and security. In this guide, you’ll learn how to upgrade your self-hosted UniFi Network Server from version 8.2.93 to version 8.6.9 and improve the certificate renewal process using Certbot. Whether you’re managing a single site or a multi-tenant system, these steps ensure a smooth upgrade and better security.

Upgrade UniFi Server dashboard screenshot

Backup Your UniFi Server

Before upgrading, always back up your server, especially if it’s running in a production environment. Without a backup, you risk losing all configurations and statistics, which can be a major setback.

Create a Snapshot or Backup:

  • If you’re running a virtual machine, take a full snapshot.
  • Navigate to Settings > System > Backups in UniFi and download the “Last 7 Days” backup to include statistics and settings.

Tip: Enable automatic backups to avoid losing data in the future.

Download the Latest UniFi Server Image

Next, update to the latest UniFi version:

Download the new image using wget:

wget [link-to-latest-image]

Install it with the dpkg -I command:

sudo dpkg -i

The installer will provide warnings on the initial start screen if additional steps are needed.

Upgrade done!

Upgrade the Hosted Platform

After updating your server, make sure the hosting platform (e.g., Ubuntu) is also up to date:

Or a combination command:

sudo apt update && sudo apt upgrade -y

Set Up a Valid SSL Certificate

To secure your UniFi server, use Certbot to streamline SSL certificate management:

  1. Add the Certbot repository and install Certbot:
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt install -y certbot python3-certbot-apache

2. Generate your certificate:

sudo certbot –apache -d yourdomain.com

Certbot SSL renewal for UniFi Server

Integrate SSL with UniFi

To link your SSL certificate to the UniFi server, use the script unifi_ssl_import.sh created by Steve.

Download and run the script

See the content of the script below, the bold part is variable and needs to be changed according to your environment:


# unifi_ssl_import.sh

# UniFi Controller SSL Certificate Import Script for Unix/Linux Systems

# by Steve Jenkins <http://www.stevejenkins.com/>

# Part of https://github.com/stevejenkins/ubnt-linux-utils/

# Incorporates ideas from https://source.sosdg.org/brielle/lets-encrypt-scripts

# Version 2.8

# Last Updated Jan 13, 2017

# REQUIREMENTS

# 1) Assumes you have a UniFi Controller installed and running on your system.

# 2) Assumes you already have a valid 2048-bit private key, signed certificate, and certificate authority

#    chain file. The Controller UI will not work with a 4096-bit certificate. See http://wp.me/p1iGgP-2wU

#    for detailed instructions on how to generate those files and use them with this script.

# KEYSTORE BACKUP

# Even though this script attempts to be clever and careful in how it backs up your existing keystore,

# it’s never a bad idea to manually back up your keystore (located at $UNIFI_DIR/data/keystore on RedHat

# systems or /$UNIFI_DIR/keystore on Debian/Ubunty systems) to a separate directory before running this

# script. If anything goes wrong, you can restore from your backup, restart the UniFi Controller service,

# and be back online immediately.

# CONFIGURATION OPTIONS

UNIFI_HOSTNAME=yourname.com

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

# CONFIGURATION OPTIONS YOU PROBABLY SHOULDN’T CHANGE

ALIAS=unifi

PASSWORD=aircontrolenterprise

#### SHOULDN’T HAVE TO TOUCH ANYTHING PAST THIS POINT ####

printf “\nStarting UniFi Controller SSL Import…\n”

# Check to see whether Let’s Encrypt Mode (LE_MODE) is enabled

if [[ ${LE_MODE} == “YES” || ${LE_MODE} == “yes” || ${LE_MODE} == “Y” || ${LE_MODE} == “y” || ${LE_MODE} == “TRUE” || ${LE_MODE} == “true” || ${LE_MODE} == “ENABLED” || ${LE_MODE} == “enabled” || ${LE_MODE} == 1 ]] ; then

        LE_MODE=true

        printf “\nRunning in Let’s Encrypt Mode…\n”

        PRIV_KEY=${LE_LIVE_DIR}/${UNIFI_HOSTNAME}/privkey.pem

        CHAIN_FILE=${LE_LIVE_DIR}/${UNIFI_HOSTNAME}/fullchain.pem

else

        LE_MODE=false

        printf “\nRunning in Standard Mode…\n”

fi

if [[ ${LE_MODE} == “true” ]]; then

        # Check to see whether LE certificate has changed

        printf “\nInspecting current SSL certificate…\n”

        if md5sum -c “${LE_LIVE_DIR}/${UNIFI_HOSTNAME}/privkey.pem.md5” &>/dev/null; then

                # MD5 remains unchanged, exit the script

                printf “\nCertificate is unchanged, no update is necessary.\n”

                exit 0

        else

        # MD5 is different, so it’s time to get busy!

        printf “\nUpdated SSL certificate available. Proceeding with import…\n”

        fi

fi

# Verify required files exist

if [[ ! -f ${PRIV_KEY} ]] || [[ ! -f ${CHAIN_FILE} ]]; then

        printf “\nMissing one or more required files. Check your settings.\n”

        exit 1

else

        # Everything looks OK to proceed

        printf “\nImporting the following files:\n”

        printf “Private Key: %s\n” “$PRIV_KEY”

        printf “CA File: %s\n” “$CHAIN_FILE”

fi

# Create temp files

P12_TEMP=$(mktemp)

# Stop the UniFi Controller

printf “\nStopping UniFi Controller…\n”

service “${UNIFI_SERVICE}” stop

if [[ ${LE_MODE} == “true” ]]; then

        # Write a new MD5 checksum based on the updated certificate

        printf “\nUpdating certificate MD5 checksum…\n”

        md5sum “${PRIV_KEY}” > “${LE_LIVE_DIR}/${UNIFI_HOSTNAME}/privkey.pem.md5”

fi

# Create double-safe keystore backup

if [[ -s “${KEYSTORE}.orig” ]]; then

        printf “\nBackup of original keystore exists!\n”

        printf “\nCreating non-destructive backup as keystore.bak…\n”

        cp “${KEYSTORE}” “${KEYSTORE}.bak”

else

        cp “${KEYSTORE}” “${KEYSTORE}.orig”

        printf “\nNo original keystore backup found.\n”

        printf “\nCreating backup as keystore.orig…\n”

fi

# Export your existing SSL key, cert, and CA data to a PKCS12 file

printf “\nExporting SSL certificate and key data into temporary PKCS12 file…\n”

#If there is a signed crt we should include this in the export

if [[ -f ${SIGNED_CRT} ]]; then

    openssl pkcs12 -export \

    -in “${CHAIN_FILE}” \

    -in “${SIGNED_CRT}” \

    -inkey “${PRIV_KEY}” \

    -out “${P12_TEMP}” -passout pass:”${PASSWORD}” \

    -name “${ALIAS}”

else

    openssl pkcs12 -export \

    -in “${CHAIN_FILE}” \

    -inkey “${PRIV_KEY}” \

    -out “${P12_TEMP}” -passout pass:”${PASSWORD}” \

    -name “${ALIAS}”

fi

# Delete the previous certificate data from keystore to avoid “already exists” message

printf “\nRemoving previous certificate data from UniFi keystore…\n”

keytool -delete -alias “${ALIAS}” -keystore “${KEYSTORE}” -deststorepass “${PASSWORD}”

# Import the temp PKCS12 file into the UniFi keystore

printf “\nImporting SSL certificate into UniFi keystore…\n”

keytool -importkeystore \

-srckeystore “${P12_TEMP}” -srcstoretype PKCS12 \

-srcstorepass “${PASSWORD}” \

-destkeystore “${KEYSTORE}” \

-deststorepass “${PASSWORD}” \

-destkeypass “${PASSWORD}” \

-alias “${ALIAS}” -trustcacerts

# Clean up temp files

printf “\nRemoving temporary files…\n”

rm -f “${P12_TEMP}”

# Restart the UniFi Controller to pick up the updated keystore

printf “\nRestarting UniFi Controller to apply new Let’s Encrypt SSL certificate…\n”

service “${UNIFI_SERVICE}” start

# That’s all, folks!

printf “\nDone!\n”

exit 0
sudo /usr/local/bin/unifi_ssl_import.sh

Automate the process by creating a cron job:
sudo nano -W /etc/cron.daily/unifi_ssl_import
Add the following script:
/usr/local/bin/unifi_ssl_import.sh

Save the file and set permissions:


sudo chown root:root /etc/cron.daily/unifi_ssl_import 
sudo chmod +x /etc/cron.daily/unifi_ssl_import

Certbot will now automatically handle SSL renewals.T

Test and Verify Certificate Renewal
Test the setup with a dry run:


sudo certbot renew --dry-run

Since Certbot uses the Apache plugin, you don’t need to stop Apache during the renewal dry-run test. Certbot handles the process seamlessly.

If you follow this guide, your UniFi Network server will be upgraded, secured with a valid SSL certificate, and automated for future updates. If you run into any issues, refer to the logs:

sudo cat /etc/cron.d/certbot

Stay updated, stay secure!

Write a Comment

Comment