Securing UniFi Cloud Key with SSL certificate from RapidSSL

During the installation of my new Ubiquiti UniFi home-network I noticed that the Cloud Key management console uses a self-signed certificate which annoyed me for days:

There is no support for Let’s Encrypt nor does Ubiquiti have a knowledge base article explaining how to install a proper certificate and their support forums are filled with the same questions. When I asked Ubiquiti support via ticket to assist I was pointed to some arbitrary 3rd party blog-post which provided instructions for installing SSL on the UniFi Cloud Controller hosted on AWS, but did not provide any information on how to install a SSL certificate onto the UniFi Cloud Key.

If you prefer Let’s Encrypt and you have a Cloudflare account you should try: UniFi SSL Cloud Key installation with Let’s Encrypt.

Backup Everything

The Cloud Key allows SFTP access as well as SSH-access. Before you continue with this guide, make a backup of the current certificate configuration. To be really safe, make a copy of /etc/ssl/private to your local computer.

After you have backed up the Cloud Key directory, delete it’s content:

Create the CSR – Certificate Signing Request

First we generate a new private key:

Then create the CSR:

The only relevant section is the “CN=” (common name) part, which should be the website name of your Cloud Key (with SSL you will address a website via a domain name instead of an IP).

Request the SSL Certificate and install the certificate

I use CheapSSLShop as it provides RapidSSL DV SSL certificates for about USD 8 / per year. Any SSL provider will operate in a similar fashion, where you need a CSR to issue the SSL certificate:

 

With RapidSSL you will receive an email which includes the certificate which you copy into /etc/ssl/private/cloudkey.crt:

It is important to have a line-feed after the “—-END CERTIFICATE—” section.

Copy the RapidSSL intermediate SSL certificate to the Cloud Key directory and you will have something like this:

The next step is to generate a PKCS12 file from your certificate, private key and intermediate RapidSSL file:

We then import the PKCS12 file into the Cloud Key keystore:

Now we adjust the permissions and delete files which we do not need:

If everything was done correctly, you can verify your certificate via nginx:

If the above command nginx -t throws an error you have probably applied the wrong intermediate certificate or forgot that line-break in your CRT.

As the last step, you restart NGINX and the Unifi Controller:

Finally, adjust your controller’s hostname:

The above commands will take a few seconds for NGINX and UniFi to restart and you will then have a beautiful green addressbar:

 

Print Friendly, PDF & Email
  • Pingback: Securing Ubiquiti UniFi Cloud Key with Let’s Encrypt SSL and automatic dns-01 challenge | naschenweng.info()

  • Pingback: Ubiquiti – Replacing my home-network and making fibre work with UniFi | naschenweng.info()

  • Tommy

    I did what you have shown us and it worked but after rebooting the CloudKey the CloudeKey started using other certificated with error that is not valid
    Issued to: San Jose
    Issued by: San Jose
    Valid from 1/26/2017 to 1/27/2027

    I removed the sym link that reference to the self signed cert and after that i can not restart the web server.

    [email protected]:~# keytool -importkeystore -deststorepass aircontrolenterprise -destkeypass aircontrolenterprise -destkeystore /usr/lib/unifi/data/keystore -srckeystore /etc/ssl/private/cloudkey.p12 -srcstoretype PKCS12 -srcstorepass aircontrolenterprise -alias unifi
    Existing entry alias unifi exists, overwrite? [no]: yes
    [email protected]:~# /etc/init.d/nginx restart [….] Restarting nginx (via systemctl): nginx.serviceJob for nginx.service failed. See ‘systemctl status nginx.service’ and ‘journalctl -xn’ for details.
    failed!
    [email protected]:~# /etc/init.d/nginx restart [….] Restarting nginx (via systemctl): nginx.serviceJob for nginx.service failed. See ‘systemctl status nginx.service’ and ‘journalctl -xn’ for details.
    failed!
    [email protected]:~# /etc/init.d/unifi restart [email protected]:~# reboot

    • That looks wrong. As far as I understand when the UCK reboots it will check the content of /etc/ssl/private/cert.tar against the files in /etc/ssl/private/ and if they are not the same, it will unpack cert.tar and overwrite files in /etc/ssl/private.

      I used the above SSL config for several days and did upgrades and reboots on the UCK and the SSL config remained intact. I have subsequently moved on to Let’s Encrypt (I have a blog-post up about how to configure this as well), and can only suggest to check the content of your /etc/ssl/private directory and the cert.tar in it.

      • Tommy

        Tommy

        I reset the CloudKey to factory default and upgraded the firmware to the latest . Have u upgraded ur CloudKey 0.5.9 and Controller 5.4.9? I use Namecheap for the certificate. I worked with normal controller on ubuntu in the past. Let me reset the CKey again and try. Do u have any sugestins where to look for errors?

        Thanks for your tutorial and help.

      • tommy

        IT WORKS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

        i reset the ckey to default CLOSED ALL open unifi ckey portal windows and install the cert in 5 min and then upgraded n rebooted 2 times. n STILL WORKS HURREY!.
        Lets hope itll stay this way.

        Thx a lot.

        • I am glad you got it sorted. I am on UCK 0.5.9 and was initially on 5.3.X and then upgraded to the 5.4.9. The SSL certs and configuration stayed. I did notice that after the 5.4.9 upgrade, I could not reach my UCK from the outside, but this was an unrelated issue.

          • Tommy

            Thanks a lot once again

            I still have a problem with setting up Unifi Ckey Guest portal. It give error msg and after acknowledgement the dialog box it redirects to the Unifi Ckey controller IP address. I set the Guest portal to “Force HTTPS redirect” ON.

            Do i have to specify in the certificate issuer address? in my case NameCheap.com? so the client browser that loads the Certificate can connect to validate to internet?

            What do you think?

          • Tommy

            Forgot to tell u, in “Allow Networks” in “Guest Portal” should i enter there IP of NameCheap.com validation address? Or something else?

          • Tommy

            Thanks a lot once again

            I still have a problem with setting up Unifi Ckey Guest portal. It give error msg and after acknowledgement the dialog box it redirects to the Unifi Ckey controller IP address. I set the Guest portal to “Force HTTPS redirect” ON.

            Do i have to specify in the certificate issuer address? in my case NameCheap.com? so the client browser that loads the Certificate can connect to validate to internet?

            What do you think?

          • I have not yet done anything with the Guest portal and just looked at the options now. It is my assumption that you can access your cloud controller via https://yourdomain.com (i.e. the same domain name you issued the cert against). If this is the case, I think you should be able to just tick all 3 redirect options under those settings and it should work.

            Perhaps you specified the redirect URL wrong or the issued cert is wrong. One suggestion would be to use the chat function and have Ubiquiti support have a look at it – I did it the other day where they used Teamviewer and helped with a configuration issue.

          • tom

            Thanks

            Yea, it redirect me to IP address ex: 192.168.22.30 instead of my domain name, and throws error dialog box. I will try the chat u told me.

            Thanks

  • Tommy

    “Huston We Got A Problem!!”

    Gerd i still got a problem with the certificate. It works for the Cloud key controller and CK itself, but it doesnt work with Guest Portal. I am getting error msg saying that the certificate is not trusted when users try load the Guest Portal Page.

    • Lol. There could be a number of reasons (fair warning: I don’t use the guest-portal, so I am making guesses): If the Guest Portal is HTTPS, check if it actually loads your cert. If it does, it could very well be a mixed content issue (i.e. the portal uses hardcoded http://-links). If it does not load your cert, then it might be another config issue or it is redirecting to the wrong URL.

      • Tommy

        Hi

        it loads on my desktop pc OK but not on my smartphone I get cert err/warning even when i try to load CKey controler login screen . I assume that my smartphone is the problem but it has no issues with loadin internet sites ex: https://google.com and others. Any idea how to get ride off that err msg on my cell?

        • To rule out any cert issues, I would run a SSL test via https://ssllabs.com/ssltest/analyze.html?d=yourdomain – I know that some CA’s (such as STARTSSL) were distrusted by Mozilla, but SSLLabs will show this.

          Perhaps the mobile phone renders the guest pages differently, causing the SSL error (one option would be to simulate the user-agent to see the pages on the desktop). You can also do this via curl/wget. Perhaps the mobile version has mixed content?

          • Tommy

            I got this:

            Additional Certificates (if supplied)
            Certificates provided 1 (1362 bytes)
            Chain issues Incomplete

            u got:

            Additional Certificates (if supplied)
            Certificates provided 3 (4727 bytes)
            Chain issues None

  • Felix Nielsen

    awsome post 🙂 – thanks

  • malk315

    Just wanted to say thanks for sharing this it worked perfect on my setup. There are a lot of guides for SSL cert on cloud key and this one is the simplest and the controller (Java Apache Tomcat) and cloudkey webserver (nginx) both serve out the certificate perfectly. Cert is available in the Java keystore and as files cloudkey.crt and cloudkey.key (not sure if nginx reads these or it also just uses the java keystore file but either way I’m happy both web servers on there present a valid cert to the browser so initial choice of cloudkey or controller page is good, controller is good, and cloudkey settings page all good).

    I’m using the Guest control with redirect of http to the cloud key and that works too. I’ve left “Redirect https” turned OFF because that will intercept things like https://google.com and produce a cert error when the guest gets the portal page instead. I also use the option to specify the hostname (fully qualified) for the portal and simply use a public DNS entry that points to the cloudkey internal IP like sitename-auth.mydomain.net When authorizing an iphone it is seamless — after picking the open guest network, the iphone checks w/ a simple request to an http site to see if a portal is active and then automatically brings up safari with lock shown upon redirect to the https portal and I can enter a voucher, free 1 hour access, or stripe based credit card auth. A test on a windows computer works too — since https redirect is off, instead of a cert warning the request times out — which is fine. I think the first time windows said additional sign in info required (windows also tries a simple http query to see if it is behind a porta). It’s simple to tell guests to visit the site website (which is regular http) in case it doesn’t notify the user additional sign in required and that triggers the redirect to the https portal name configured i.e. sitename-auth.mydomain.net and I’ve got that set to the internal IP of the cloudkey i.e. I’m using 172.16.20.5 as the sitename-auth.mydomain.net ip address and the browser is totally happy with the RapidSSL cert. Tested with Chrome and Firefox on the Win 7 box. My fedora linux box chrome browser is totally happy w/ the management web interface via https using sitename-auth.mydomain.net It’s nice not having the warning there. Also nice that the guests before authorization and after authorization can’t access any of my network infrastructure which is on 172.16.x.x network which is automatically blocked for guests that are authorized. I’ve got a second wireless network with WPA PSK that isn’t guest so staff can get to all of the UBNT gear etc.

    Thanks again Gerd for your work on this.

    Also a reboot of the cloudkey and all comes up fine — I checked md5sums of the files in /etc/ssl/private and none of them changed after the reboot, cert still working great. I’m going to be set now with my deployment as a hotspot with full voucher and credit card integration.

    Cheers.

    • I am so glad that this works. I am also quite happy with this simple way of doing it. I have upgraded controller firmware a number of times as well as rebooted and config just survives. Since I have implemented it this way, the cert has been auto-renewed twice without an issue. It is quite surprising that Ubiquiti has not implemented it this way as it is really straight forward.

      • malk315

        Thought I’d share a screenshot of the portal settings I’m using:

        https://uploads.disquscdn.com/images/2701f347243b5dfbfbd297dfa5de4d8b7553c21dbe6e1ee219564813bd58584a.png

        “Promotional URL” goes to the site owner’s website and usually that is http. Helps a lot with android notification for “Sign-in required” after you authenticate with the secure portal using CC or voucher if you don’t have a promotional URL it will just sit at the portal page creating confusion. Promotional URL will be loaded upon successful portal usage.

        “Use secure portal” checked makes the portal take advantage of all of the work Gerd has shared — if you don’t specify a hostname “Redirect using hostname” the user gets redirected to the IP of the portal i.e. https://172.16.20.5:8443/blah/blah in my case and you get a cert warning since you now have a REAL cert. So make sure you specify your cert’s CN with “Redirect using hostname” my example is https://site-auth.mydomain.net

        The final piece is to add an entry in your public DNS provider my example here is mydomain.net add an A record with the the IP of your cloudkey — an internal IP is fine following my example it would be 172.16.20.5

        I also use dynamic DNS on the security gateway and setup PPTP w/ local auth so I can easily VPN in w/ linux or windows PPTP to have full access to unifi and Airmax devices on my deployment. What I do for dynamic DNS is easydns with a name like site.mydomain.net. So I have two public A-records, site.mydomain.net is the public IP of the gateway updated by dynamic DNS, a static would be fine too, and I can VPN there. site-auth.mydomain.net is the A record (static) for the cloudkey internal IP for portal and when VPN’d or on site I can go to https://site-auth.mydomain.net to get the controller with happy green padlock.

        Perhaps an event better DNS name for the cloudkey would be site-cloudkey.mydomain.net Per Gerd’s instructions I set the hostname of the controller to site-auth.mydomain.net so it matches what the cert has. Thanks again!

        Cheers

  • malk315

    So Android was not trusting the cert when my Droid Turbo 2 or Samsung Galaxy tab visits the secure portal. This is because the Java keystore was missing my cert’s intermediate cert from rapidssl and I read that Android demands both be presented by the server

    I figured out how to get both the cert and intermediate cert into the keystore and cloudkey.crt and now iphone, android, chrome on windows, firefox on windows, edge on windows 10, and chrome on linux are all happy with the cert as presented by the portal!

    Here’s what I did differently — put both the signed cert and intermediate rapidssl cert into cloudkey.crt with no extra newlines anywhere, order is important for android:

    cd /etc/ssl/private
    cat signed.crt rapidssl.crt > cloudkey.crt

    Now create a PKCS12 using openssl this way:

    openssl pkcs12 -export -in signed.crt -inkey cloudkey.key -certfile cloudkey.crt -out unifi.p12 -name unifi -password pass:aircontrolenterprise

    Now use keytool to create the java keystore:

    keytool -importkeystore -srckeystore unifi.p12 -srcstoretype PKCS12 -srcstorepass aircontrolenterprise -destkeystore unifi.keystore.jks -storepass aircontrolenterprise

    Check that your keystore has both your signed cert and the rapidssl intermediate in it:

    keytool -list -v -keystore unifi.keystore.jks

    use aircontrolenterprise for the password and verify you get certificate 1 with your CN and certificate 2 with rapidssl intermediate in my case the SHA256 rapidssl intermediate:

    Certificate[2]:
    Owner: CN=RapidSSL SHA256 CA, O=GeoTrust Inc., C=US

    The above is all done from the /etc/ssl/private directory. Now you can remove unneeded extra files, create the cert.tar and fix permissions. Note the cloudkey.crt has both your sigend cert and RapidSSL intermediate in it concatenated with no extra newlines.

    Startup the cloudkey service and restart the nginx service.
    You can also have nginx check it’s config as Gerd documented and in my case it passes.

    This is AWESOME. I think Tommy’s problem from a few months ago where he reported his tablet on the portal didn’t like the cert is likely Android being fussy about the Tomcat java server not feeding it both the signed cert and intermediate cert. The root cert will already be on all devices out there I don’t believe it’s expected that the root cert be included in the chain.

    I’m going to wipe my device and re-test these instructions and make sure both nginx and Tomcat servers are good and make sure reboots of the cloudkey don’t wreck anything.

    Cheers!