stevejenkins/unifi-linux-utils

Just fyi: Function which updates the Cloud Key management interface as well

Closed this issue · 1 comments

I use this function in a script as a Home Assistant addon, so if you use this, you might have to change a few logging lines. It also remotes to SSH and i removed the functionality which i didn't need. Thanks for your work!

function unifi_renew() {

    bashio::log.info "Starting UniFi Controller SSL Import..."
    
    local domainWithoutWildcard=${DOMAIN:1}
    local domainString="${domainWithoutWildcard//[\.]/_}"
    local CERT_DIR_NAME="star${domainString}"
    local UNIFI_HOSTNAME=$(bashio::config 'unifi.hostname')
    local UNIFI_USERNAME=$(bashio::config 'unifi.username')
    export SSHPASS=$(bashio::config 'unifi.password') 

    # CONFIGURATION OPTIONS FOR CLOUDKEY
    local UNIFI_SERVICE=unifi
    local UNIFI_DIR=/var/lib/unifi
    local JAVA_DIR=/usr/lib/unifi
    local KEYSTORE=${JAVA_DIR}/data/keystore
    local ALIAS=unifi
    local PASSWORD=aircontrolenterprise

    bashio::log.info "Running in Let's Encrypt Mode..."
    local PRIV_KEY=${CERT_DIR}/${CERT_DIR_NAME}/privkey.pem
    local CHAIN_FILE=${CERT_DIR}/${CERT_DIR_NAME}/fullchain.pem
    local PRIV_KEY_MD5=${CERT_DIR}/${CERT_DIR_NAME}/privkey.pem.md5
    local PRIV_KEY_CLOUDKEY=/etc/ssl/private/cloudkey.key
    local CHAIN_FILE_CLOUDKEY=/etc/ssl/private/cloudkey.crt

    # Check to see whether LE certificate has changed
     bashio::log.info "Inspecting current SSL certificate..."
    if md5sum -c "${PRIV_KEY_MD5}" &>/dev/null; then
        # MD5 remains unchanged, exit the script
         bashio::log.info "Certificate is unchanged, no update is necessary."
        return 0
    else
        # MD5 is different, so it's time to get busy!
         bashio::log.warning "Updated SSL certificate available. Proceeding with import..."
    fi

    # Verify required files exist
    if [[ ! -f ${PRIV_KEY} ]] || [[ ! -f ${CHAIN_FILE} ]]; then
        bashio::log.error "Missing one or more required files. Check your settings."
        return 1
    else
        # Everything looks OK to proceed
        bashio::log.info "Importing the following files:"
        bashio::log.info "Private Key: $PRIV_KEY"
        bashio::log.info "CA File: $CHAIN_FILE"

        local PRIV_KEY_CONTENT=$( cat $PRIV_KEY )
        local CHAIN_FILE_CONTENT=$( cat $CHAIN_FILE )
    fi

    # Write a new MD5 checksum based on the updated certificate	
    bashio::log.info "Updating certificate MD5 checksum..."
    md5sum "${PRIV_KEY}" > "${PRIV_KEY_MD5}"

    # Set verbose parameter
    if [ "$DEBUG"=true ] ; then
        DEBUG_PARAM="-v"
    else
        DEBUG_PARAM=""
    fi

    bashio::log.info "Starting SSH session to Unifi CloudKey controller..."
    sshpass $DEBUG_PARAM -e ssh $DEBUG_PARAM -T -o StrictHostKeyChecking=accept-new ${UNIFI_USERNAME}@${UNIFI_HOSTNAME} <<:

    # Create temp files
    P12_TEMP=\$(mktemp)

    # Stop the UniFi Controller
    printf "\nStopping UniFi Controller...\n"
    service "${UNIFI_SERVICE}" stop

    # 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
    
    # Create double-safe certificate private key backup
    if [[ -s "${PRIV_KEY_CLOUDKEY}.orig" ]]; then
        printf "\nBackup of original certificat eprivate key exists!\n"
        printf "\nCreating non-destructive backup as cloudkey.key.bak...\n"
        cp "${PRIV_KEY_CLOUDKEY}" "${PRIV_KEY_CLOUDKEY}.bak"
    else
        cp cp "${PRIV_KEY_CLOUDKEY}" "${PRIV_KEY_CLOUDKEY}.orig"
        printf "\nNo original certificate private key backup found.\n"
        printf "\nCreating backup as cloudkey.key.orig...\n"
    fi

    # Create double-safe certificate chain file backup
    if [[ -s "${CHAIN_FILE_CLOUDKEY}.orig" ]]; then
        printf "\nBackup of original certificate chain file exists!\n"
        printf "\nCreating non-destructive backup as cloudkey.crt.bak...\n"
        cp "${CHAIN_FILE_CLOUDKEY}" "${CHAIN_FILE_CLOUDKEY}.bak"
    else
        cp "${CHAIN_FILE_CLOUDKEY}" "${CHAIN_FILE_CLOUDKEY}.orig"
        printf "\nNo original certificate chain file backup found.\n"
        printf "\nCreating backup as cloudkey.crt.orig...\n"
    fi

    # Export your new SSL key, cert, and CA data to a PKCS12 file
    printf "\nExporting SSL certificate and key data into temporary PKCS12 file...\n"
    printf "%s" "$PRIV_KEY_CONTENT" > "\$PRIV_KEY_CLOUDKEY"
    printf "%s" "$CHAIN_FILE_CONTENT" > "\$CHAIN_FILE_CLOUDKEY"
    openssl pkcs12 -export -in "\${CHAIN_FILE_CLOUDKEY}" -inkey "\${PRIV_KEY_CLOUDKEY}" -out "\${P12_TEMP}" -passout pass:"${PASSWORD}" -name "${ALIAS}"

    # 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
    
    # Reloading the UniFi CloudKey management interface to pick up the updated certificates
    printf "\nReloading the UniFi CloudKey management interface to apply the new Let's Encrypt SSL certificate...\n"    
    nginx -s reload

    # That's all, folks!
    printf "\nDone!\n"
:
    bashio::log.info "Certificate succesfully updated on the Unifi CloudKey controller..."
    return 0
}

Closed as i posted this only for reference