Hosted Unifi controller with Let’s Encrypt SSL take 2!

Unifi Dashboard with SSL

I visited this idea months ago, but for anyone who implemented it, it has been a nightmare.  Each subsequent Unifi controller update broke the https in new and exciting ways.  After remaining a very squeaky wheel with Ubiquity support, they’ve pushed out a version that should permanently resolve the problems. They even made promises of native Let’s Encrypt support.  All this will prove true of false with time, but for now i wanted to share my working procedure for Unifi controller version 5.9.32.

This solution required me to become more familiar with Java’s keytool then i would have otherwise.  Unifi has a hardcoded keytool path and password, don’t change that (thanks Corey F @ubnt). i don’t think alias matter, but they must be consistent.  I used mykey.  We start by generating a key and a code signing request for our domain.  For permissions reasons, we will want to do this as root. . .
cd /var/lib/unifi
keytool -genkeypair -alias mykey -keyalg RSA -keysize 2048 -keystore keystore -dname "CN=custom.domain.name" -storepass aircontrolenterprise

Now we export the csr file we will give to Let’s Encrypt.
keytool -certreq -alias mykey -keystore keystore -file custom.domain.name.csr -ext san=dns:custom.domain.name -storepass aircontrolenterprise

Now we run the interactive certbot script to prove the domain is actually yours before they hand out a cert.  Follow the instructions you can use DNS or hosting a file to verify.
certbot certonly --manual --csr custom.domain.name.csr

Once this is done, pay attention to the output, certbot will tell you the path to the signed certificate and the certificate chain which includes the signed certificate and the intermediate certificate.  something like this:
Server issued certificate; certificate written to /var/lib/unifi/0000_cert.pem
Cert chain written to 8
Cert chain written to 9
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/var/lib/unifi/0001_chain.pem
Your cert will expire on 2019-02-14. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

Now note these paths and file names.  take a peak at your 0000_cert.pem, 0000_chain.pem, and 0001_chain.pem.  Keytool, wants everything separate.  Make your the intermediate file (0000_chain.pem) has only one key.  Now is also a good time to grab Let’s Encrypt’s Root certificate.  In this example we called it le-root.pem in the some directory.  Once we have the root and intermediate certificates handy and our own cert signed, we are ready to install them.
keytool -import -trustcacerts -alias CARoot -file /var/lib/le-root.pem -keystore keystore -storepass aircontrolenterprise
keytool -import -trustcacerts -alias intermediate -file /var/lib/unifi/0000_chain.pem -keystore keystore -storepass aircontrolenterprise
keytool -import -trustcacerts -alias mykey -file /var/lib/unifi/0000_cert.pem -keystore keystore -storepass aircontrolenterprise

Each command should return an affirmative message, the first 2 should say:
Certificate was added to keystore
the last one
Certificate reply was installed in keystore
Finally, I deleted the self signed certificate that came pre-installed…
keytool -delete -alias unifi -keystore keystore -storepass aircontrolenterprise

That last command may not have been necessary. Now that we are done, restart the unifi controller…
/etc/init.d/unifi restart