From 5dd1328c8e15281f0e256d35784fb3d012bf385a Mon Sep 17 00:00:00 2001 From: 3VAbdAVE Date: Wed, 17 Apr 2024 11:08:23 -0400 Subject: [PATCH] Tested on Unifi Dream Machine, updated header text. Back up existing certificates in case something goes wrong. Partial fixes in #3359 Comment #1817258702 and others - Unifi removed keytool from OS, which breaks the ability to deploy certificates used by the console. Deciding how to fix is up to the sysadmin, inserted some advice when it fails. Comment #2061486940 - Automatically set the cipher suites in system configuration. --- deploy/unifi.sh | 69 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/deploy/unifi.sh b/deploy/unifi.sh index a864135e..68bce9d6 100644 --- a/deploy/unifi.sh +++ b/deploy/unifi.sh @@ -5,6 +5,18 @@ # - self-hosted Unifi Controller # - Unifi Cloud Key (Gen1/2/2+) # - Unifi Cloud Key running UnifiOS (v2.0.0+, Gen2/2+ only) +# See below regarding keytool. Not tested. +# - Unifi Dream Machine +# This has not been tested on other "all-in-one" devices such as +# UDM Pro or Unifi Express. +# +# OS Version v2.0.0+ +# Network Application version 7.0.0+ +# OS version ~3.1 removed java and keytool from the UnifiOS. These must be +# manually installed by the system owner at their own risk, as +# doing so may invalidate official Ubiquiti support/warranty. +# `apt update && apt install openjdk-11-jre-headless -y` +# # Please report bugs to https://github.com/acmesh-official/acme.sh/issues/3359 #returns 0 means success, otherwise error. @@ -74,14 +86,30 @@ unifi_deploy() { _reload_cmd="" # Unifi Controller environment (self hosted or any Cloud Key) -- - # auto-detect by file /usr/lib/unifi/data/keystore: + # auto-detect by file /usr/lib/unifi/data/keystore + # Additional detection of OS version to handle missing keytool. _unifi_keystore="${DEPLOY_UNIFI_KEYSTORE:-/usr/lib/unifi/data/keystore}" if [ -f "$_unifi_keystore" ]; then - _info "Installing certificate for Unifi Controller (Java keystore)" _debug _unifi_keystore "$_unifi_keystore" if ! _exists keytool; then - _err "keytool not found" + _err "keytool not found." + _keytool_instructions=$(cat <<-EOF + Unifi removed keytool from the console OS after version 3. + You may be able to reinstall with + "apt update && apt install openjdk-11-jre-headless -y" + THIS MAY AFFECT UBIQUITI SUPPORT, DO SO AT YOUR OWN RISK. + It's also possible that apt will not work in future versions. + + If you don't want to (or can't use apt), then it's recommended + to deploy from a remote host via SSH. See + https://github.com/acmesh-official/acme.sh/wiki/deployhooks#examples-using-ssh-deploy + +EOF +) + _info "$_keytool_instructions" return 1 + else + _info "Installing certificate for Unifi Controller (Java keystore)" fi if [ ! -w "$_unifi_keystore" ]; then _err "The file $_unifi_keystore is not writable, please change the permission." @@ -99,13 +127,23 @@ unifi_deploy() { return 1 fi + # Save the existing keystore in case something goes wrong. + cp -f "${_unifi_keystore}" "${_unifi_keystore}"_original + _info "Previous certificate and key saved to ${_unifi_keystore}_original." + + # May not be necessary, but seems more reliable + _debug "Remove existing key from keystore: $_unifi_keystore" + if keytool -delete -alias unifi -keystore "$_unifi_keystore" \ + -deststorepass "$_unifi_keypass"; then + _debug "Successfully removed old certificate from keystore." + fi + _debug "Import into keystore: $_unifi_keystore" if keytool -importkeystore \ -deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \ -srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \ -alias unifi -noprompt; then _debug "Import keystore success!" - rm "$_import_pkcs12" else _err "Error importing into Unifi Java keystore." _err "Please re-run with --debug and report a bug." @@ -113,6 +151,24 @@ unifi_deploy() { return 1 fi + # Update unifi service for certificate cipher compatibility + if ${ACME_OPENSSL_BIN:-openssl} pkcs12 \ + -in "$_import_pkcs12" \ + -password pass:aircontrolenterprise \ + -nokeys | ${ACME_OPENSSL_BIN:-openssl} x509 -text \ + -noout | grep -i "signature" | grep -iq ecdsa > /dev/null 2>&1; then + cp -f /usr/lib/unifi/data/system.properties /usr/lib/unifi/data/system.properties_original + _info "Updating system configuration for cipher compatibility." + _info "Saved original system config to /usr/lib/unifi/data/system.properties_original" + sed -i '/unifi\.https\.ciphers/d' /usr/lib/unifi/data/system.properties + echo "unifi.https.ciphers=ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES128-GCM-SHA256" &>> /usr/lib/unifi/data/system.properties + sed -i '/unifi\.https\.sslEnabledProtocols/d' /usr/lib/unifi/data/system.properties + echo "unifi.https.sslEnabledProtocols=TLSv1.3,TLSv1.2" &>> /usr/lib/unifi/data/system.properties + _info "System configuration updated." + fi + + rm "$_import_pkcs12" + if systemctl -q is-active unifi; then _reload_cmd="${_reload_cmd:+$_reload_cmd && }service unifi restart" fi @@ -165,6 +221,11 @@ unifi_deploy() { return 1 fi + # Save the existing certs in case something goes wrong. + cp -f "${_unifi_core_config}"/unifi-core.crt "${_unifi_core_config}"/unifi-core_original.crt + cp -f "${_unifi_core_config}"/unifi-core.key "${_unifi_core_config}"/unifi-core_original.key + _info "Previous certificate and key saved to ${_unifi_core_config}/unifi-core_original.crt/key." + cat "$_cfullchain" >"${_unifi_core_config}/unifi-core.crt" cat "$_ckey" >"${_unifi_core_config}/unifi-core.key"