Last active
April 3, 2024 02:32
-
-
Save Nepherte/eb043826b701dfcc887a87202f1907dd to your computer and use it in GitHub Desktop.
Script to import an SSL certificate into a UniFi Controller.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# 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=ui.nepherte.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=no | |
LE_LIVE_DIR=/etc/letsencrypt/live | |
# THE FOLLOWING OPTIONS NOT REQUIRED IF LE_MODE IS ENABLED | |
PRIV_KEY=/etc/letsencrypt/live/ui.nepherte.com/privkey.pem | |
SIGNED_CRT=/etc/letsencrypt/live/ui.nepherte.com/cert.pem | |
CHAIN_FILE=/etc/letsencrypt/live/ui.nepherte.com/fullchain.pem | |
# 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment