Feed on
Posts
Comments

unifi-ssl-header

For the longest time I wondered why Chrome would never save the password of my Ubiquiti UniFi controllers’ web interfaces. It turns out because the UniFi controller software ships out of the box with a self-signed SSL/TLS cert that’s untrusted, Chrome does a smart thing and won’t prompt you to save the password for the page.

The way to fix this (and otherwise let your browser trust the web UI) is to install your own certificate into the UniFi controller key store, either buy one from a commercial CA or your own organization’s CA that your browsers trust. Unfortunately it looks like there’s a lot of confusion on how to do this, even on Ubiquiti’s help pages there are articles that are titled for UniFi but are really geared for EdgeMAX products.

However you wind up with a trusted cert to import, here’s how to do it for UniFi controllers running on Mac OS X or Linux. Really both are the same procedure since UniFi uses Java’s keystore under the hood on both platforms, the paths for files are different. Ideally you’ll want to script this or set up something like a Chef recipe to manage the files for you, because you’ll need to repeat this whenever the cert expires or the key gets compromised.

Assumptions:

  • You have a way to get a trusted certificate to upload. How to self sign or setting up a CA is not covered here.
  • The UniFi (Java) keystore expects to import certificates in DER (binary) format. If you have certificates in PEM (which is really BASE64/ ASCII armored DER), you’ll need to use openssl or something to convert the PEM files to DER.
  • You’ll need to use the UniFi tool to generate certificate requests (CSRs). I didn’t put any time into looking at importing completely new private keys into the keystore, I just signed the CSR that was generated.
  • I run my own wann.net certificate authority (CA) for issuing certs for all of my devices. My browsers on all of my laptops and phones already trust this.
  • You know how to work with the CLI

Mac OS X

Java (JAR) contents of the UniFi controller are installed to /Applications/UniFi.app/Contents/Resources/. The lib/ace.jar is a UniFi-provided Java tool to manipulate the controller and key store.

Certificate requests and the keystore is stored in the data/ subdirectory which is a symlink to a user’s Library/Application Support directory, e.g. /Users/bwann/Library/Application Support/UniFi/data. (This is what preserves controller data between installs.) You must be in the main Resources/ directory before you can work with the UniFi keystore, else the tool gets unhappy with paths and can’t find things.

Generating a certificate request from the UniFi controller

The UniFi controller can generate a CSR for you, and it’ll keep the corresponding key in the local keystore.

# cd /Applications/UniFi.app/Contents/Resources/
# java -jar lib/ace.jar new_cert unifi.wann.net wann.net Fremont CA US
Certificate for unifi.wann.net generated

You should now have CSRs in PEM and DER format in the data/ directory:

# ls -l data/unifi*
-rw-r--r-- 1 root staff 708 Dec 31 14:42 data/unifi_certificate.csr.der
-rw-r--r-- 1 root staff 1042 Dec 31 14:42 data/unifi_certificate.csr.pem
#

Take the CSR (whichever format you prefer) and sign it with your CA.

Converting PEM certificates to DER

If you’re running your own CA, you’ll need to convert your CA’s public root key to DER format too in order to import it. In my case I always work with PEM certificates, so I need to convert both my newly signed certificate and root certificate:

# openssl x509 -outform der -in data/wannnet-ca-current-cert.pem -out data/wannnet-ca-current-cert.der
# openssl x509 -outform der -in data/unifi_certificate.cert.pem -out data/unifi_certificate.cert.der

You can store both of these DER files in the data/ directory.

Importing the certificates

Use the import_cert argument to ace.jar to import both the root CA and host certificate:

# java -jar lib/ace.jar import_cert data/unifi_certificate-cert.der data/wannnet-ca-current-cert.der
parse wannnet-ca-current-cert.der (DER, 1 certs): EMAILADDRESS=pk@wann.net, OU=wann.net CA, O=wann.net, L=Fremont, ST=California, C=US
parse unifi_certificate-cert.der (DER, 1 certs): CN=unifi.wann.net
Importing signed cert[unifi.wann.net]
... issued by [EMAILADDRESS=pk@wann.net, OU=wann.net CA, O=wann.net, L=Fremont, ST=California, C=US]
Certificates successfuly imported. Please restart the UniFi Controller.

Restart the UniFi controller. Done!

Linux (CentOS/Debian)

Basically the exact same process on CentOS/Debian/Ubuntu, except the paths to UniFi data is different. On at least Ubuntu the main binaries of the controller are installed to /usr/lib/unifi/, with /usr/lib/unifi/data/ being a symlink to /var/lib/unifi/.

Generating a certificate request from the UniFi controller

# cd /usr/lib/unifi
# java -jar lib/ace.jar new_cert unifi.wann.net wann.net Fremont CA US
 Certificate for unifi.wann.net generated
You should now have CSRs in PEM and DER format in the data/ directory:
# ls -l data/unifi*
-rw-r--r-- 1 root root 712 Dec 31 18:04 data/unifi_certificate.csr.der
-rw-r--r-- 1 root root 1050 Dec 31 18:04 data/unifi_certificate.csr.pem

Take the CSR (whichever format you prefer) and sign it with your CA.

Converting PEM certificates to DER

Follow the exact same steps in the OS X section to use openssl to convert from PEM to DER if necessary.

Importing the certificates

Use the import_cert argument to ace.jar to import both the root CA and host certificate:

# java -jar lib/ace.jar import_cert data/unifi_certificate-cert.der data/wannnet-ca-current-cert.der
 parse wannnet-ca-current-cert.der (DER, 1 certs): EMAILADDRESS=pk@wann.net, OU=wann.net CA, O=wann.net, L=Fremont, ST=California, C=US
 parse unifi_certificate-cert.der (DER, 1 certs): CN=unifi.wann.net
 Importing signed cert[unifi.wann.net]
 ... issued by [EMAILADDRESS=pk@wann.net, OU=wann.net CA, O=wann.net, L=Fremont, ST=California, C=US]
 Certificates successfuly imported. Please restart the UniFi Controller.

Restart the UniFi controller

service unifi restart

Done!

Using keytool

There’s a Java utility called keytool usually on your system you can use to view or work with the key store stored by the UniFi controller. For sake of compatibility and time I elected to use the import function of lib/ace.jar, but for the #yolo crowd you can play with this to make modifications to the keystore directly.

For example,  to list which certificates are in the key store file (by default there’s no keystore password):

keytool -list -keystore data/keystore

Verbose listing with certificate details:

keytool -list -v -keystore data/keystore

2 Responses to “Installing SSL/TLS certs in UniFi controllers”

  1. Dan says:

    Thanks you for this write up! I will definitely be linking to it when I write this up later.

    I am using a PositiveSSL cert and here is what I had to do.

    #1 – Make sure to download all of the intermediate certs from here for PostiveSSL (https://support.comodo.com/?/Knowledgebase/Article/View/620) and upload them to the /usr/lib/unifi/data directory
    #2 – Run this for the import command: ‘java -jar lib/ace.jar import_cert data/unifi_XXXXX.der data/COMODORSADomainValidationSecureServerCA.crt data/COMODORSAAddTrustCA.crt data/AddTrustExternalCARoot.crt’

    That successfully added my cert as well as all other necessary certs. I appreciate you taking the time to write this up!

  2. Axel says:

    Hi,
    thanks for the Mac specific info, it’s always hard to figure out which java lib directory to traverse. Also thanks to Dan for the extra info.

    I noticed that in the current version (5.4.16), you don’t need to convert to DER anymore, and you can just use the PEM crt file that, in my case, PositiveSSL returns.

Leave a Reply