The whole Let’s Encrypt thing has the side effect of making me cranky every few months as I go around checking what expired, what automatically renewed, and what needs more babysitting.
Today I want to bitch about the Ubiquiti UniFi controller software. As far as I can tell even the mere CONCEPT of updating TLS certificates STILL does not exist anywhere in the controller or the support documentation. Sure they make a nice web UI to manage your 11ty-dozen wireless APs, cameras, doorbells, LED panels, key readers, and whatever thing they’re pushing this month, but keeping the web UI secure and up to date in a post-Snowden world? Nah, screw you. Not even a clumsy annoying web way to do it, no “click here to re-generate a self-signed certificate”, not even a sanctioned command line way to do it. You’re utterly on your own to figure it out. I guess this is one carrot of forcing people to use their cloudy UI.com service.
This has lead to countless people like me reinventing the wheel since 2016 and poking at the Java keystore directly with the old ACE.jar and keytool tools. You did naturally assume it’s a Java keystore the first time you encountered self-signed or expired certs warnings, right?
It’s even worse now when you layer all the Let’s Encrypt tools on top of it, because virtually all of them assume you’re on some form of Ubuntu or Linux. You won’t know it until you try to run a deploy script or read the code. I’m running it on MacOS which is a sanctioned platform and gets regular releases. The official acme.sh/deploy/unifi.sh claims it supports self-hosted, but it really assumes self-hosted on Linux. I’m afraid to know what the Windows people have to deal with.
What I wound up doing is using and tweaking the unifi_ssl_import.sh script from https://github.com/stevejenkins/unifi-linux-utils. This takes care of exporting a PKCS12 file and importing it into the Java keystore. It assumes Certbot and Linux, but it easily adapted to Acme.sh paths on MacOS. Thank god this isn’t some gigantic monolith of bash and it is fairly straightforward. I run only this script and it takes care of updating the UniFi keystore.
It is not automatic upon renewal, and doesn’t automatically restart the Unifi software. Those are problems for another day, maybe in 100 more days.
-UNIFI_HOSTNAME=hostname.example.com +UNIFI_HOSTNAME=${HOSTNAME} # Add this to override all of the Fedora/CentOS/Ubuntu/CloudKey paths # +# MacOS paths +UNIFI_DIR="${HOME}/Library/Application Support/UniFi" +JAVA_DIR="${UNIFI_DIR}" +KEYSTORE="${UNIFI_DIR}/data/keystore" # Script assumes Certbot paths, tweak for acme.sh +# MacOS, this time for acme.sh +ACMEBASE="${HOME}/.acme.sh/${UNIFI_HOSTNAME}" +PRIV_KEY="${ACMEBASE?}/${UNIFI_HOSTNAME}.key" +SIGNED_CRT="${ACMEBASE?}/${UNIFI_HOSTNAME}.cer" +CHAIN_FILE="${ACMEBASE?}/ca.cer" # Add -legacy option to openssl in two spots + openssl pkcs12 -export -legacy\
Maybe someday I’ll get around to sending in a PR to add MacOS support for the deploy script, but not today. I’ve already spent too much time shaving this yak and have other things to do.
Unhelpful responses from the peanut gallery on this issue:
- Just type in “thisisunsafe” every time in Chrome! fucking hell, this isn’t even attempting to solve the problem. would you tell your director or CISO to do this?
- Just proxy it behind Apache/Nginx/Linux! no. now I have to support and configure two things.
- Just run it on Linux! Bro, I swear a raspberry pi is all you need, bro please! no. see above, now I have to support an entirely different piece of hardware and OS.
- Just don’t run the web UI! bro, their entire product revolves around running a web UI, how do YOU run it?
Or you know, Ubiquiti could actually provide a mechanism for uploading a new certificate+key pair.