05 Nov 2017

Unifi Cloud Key: Custom SSL Certificate

Eliminate annoying HTTPS warnings with your own valid SSL certificate.

On my home network, I have a pfSense box as a gateway for a few Ubiquiti switches and access points. Ubiquiti makes great networking gear for small- to medium-sized deployments. You can control all your Ubiquiti products using the Unifi Controller app, which you can run on any computer on your network.

If you don't have a dedicated server to use as the Unifi Controller, or you just want something with a smaller footprint, Ubiquity provides a small, POE-powered device called the Cloud Key which you can use as the Controller for your network. It's kind of like a Raspberry Pi, but comes with all the Ubiquity controller software preinstalled.

To use the Cloud Key, you just plug it into your switch, figure out it's IP address, and point your web browser there. Of course, not knowing where it's going to be deployed, the Cloud Key just presents a self-signed HTTPS certificate by default—causing modern browsers to emit all kinds of draconian warning messages. I have a DHCP mapping and hostname configured for the Cloud Key in pfSense, so I can reach it from my home network by going to cloudkey.c0ffee.net. I also have a wildcard SSL certificate from Comodo. So I thought to myself, "I'll just copy my certificate over to the Cloud Key, change a setting somewhere, and I can get rid of that stupid error message!"

Unfortunately, this was such a royal pain that I decided to document the necessary steps so that the next poor soul that attempts this doesn't waste as much of the his life in the process as I did.

Parting the Clouds

In the instructions below, I'm going to assume you have a certificate pair for example.com, and your Cloud Key is located at cloudkey.example.com. You will also need the root certificate (as well as any intermediate certificates) for your certificate authority concatenated into a single file. The intermediate certificate should be placed before the root certificate. I'm going to assume you named this file chain.crt.

First, copy the certificates to the Cloud Key. The root password should be the same one you use to log into the web interface.

scp chain.crt example.com.{crt,key} root@unifi.example.com:

SSH to your Cloud Key:

ssh root@unifi.example.com

Now, the fun begins.

# stop the unifi web service
service unifi stop

# backup the default certificate
mkdir backup
cp -r /etc/ssl/private/ backup

# remove the default SSL bundle
rm /etc/ssl/private/cert.tar

# MAGIC - discovered through random forum posts, wailing, and gnashing 
# of teeth
openssl pkcs12 -export -in example.com.crt -inkey example.com.key -out example.com.p12 -name unifi -CAfile chain.crt -caname root
keytool -importkeystore -deststorepass aircontrolenterprise -destkeypass aircontrolenterprise -destkeystore /usr/lib/unifi/data/keystore -srckeystore example.com.p12 -srcstoretype PKCS12 -srcstorepass aircontrolenterprise -alias unifi
cp example.com.crt /etc/ssl/private/cloudkey.crt
cp example.com.key /etc/ssl/private/cloudkey.key
rm /etc/ssl/private/ssl-cert-snakeoil.key
chown root:ssl-cert /etc/ssl/private/*
chmod 640 /etc/ssl/private/*
tar -cvf cert.tar *
chown root:ssl-cert cert.tar
chmod 640 cert.tar
service nginx restart

# NOTE: if you have an ECC certificate like me, you must also complete
# the following magic incantations.
# (if you don't know what an ECC certificate is, just ignore this part.)
#
# echo "unifi.https.sslEnabledProtocols=TLSv1.2" >> /usr/lib/unifi/data/system.properties
# echo "unifi.https.ciphers=TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256" >> /usr/lib/unifi/data/system.properties

# finally, restart the unifi service
service unifi start

After that, you should be able to access the Cloud Key using your existing SSL certificate. You should change your "Controller Hostname/IP" in the Unifi controller settings to your FQDN (cloudkey.example.com, in this case). I also changed my "Device Name" in the Cloud Key settings to cloudkey for consistency.

Now, join me in complaining to Ubiquiti that this isn't possible to accomplish in the Cloud Key's web interface.