Ubiquiti's UniFi Controller is an excellent way to deploy and manage home and SMB networks. If you have multiple networks (sites) to manage, having your UniFi controller hosted in the cloud is recommended for easy centralized control of your UniFi devices. Having UniFi in the cloud however poses some security risks and challenges that should be addressed as soon as the UniFi Controller is created. In this article, we will show how to secure UniFi from start to finish with best practices. We will be utilizing a server hosted on Digital Ocean, however these concepts will be similar on any hosted deployment.
To create your hosted UniFi server, you will first need an account with Digital Ocean. If you do not have a Digital Ocean account, you can click the Digital Ocean logo below to sign up and receive $10.00 credit towards your first droplet (server). This essentially means you can get 2 months of the lowest tier droplet for free.
Part 1 - Create a Digital Ocean Droplet
The first step is to create your Digital Ocean droplet. From the Digital Ocean dashboard, click the green 'Create' button and select 'Droplets.' Under 'Distributions,' select Ubuntu 16.04.03 x64. (Version numbers may change over time, but you want a 64 bit version of a Ubuntu 16 server).
Next, choose your Droplet size. If you are setting up UniFi for a small handful of sites, or if you are just playing around/testing, then the $5.00/month 1GB RAM /1 CPU Droplet size is perfectly fine. If, however you are going to be using this in production, I would recommend bumping up to the $10/month or $20/month droplet sizes.
Next, scroll down and choose a data center. This can be any data center, but keep in mind that in general, the further away from you a data center is geographically, the higher the network latency will be. I typically choose the closest data center to my customer. In this case, I'm going to choose San Francisco 2.
You can skip over the additional options and the SSH keys (we will be setting up SSH key authentication later), but you should set up a hostname. In my case, we're going to use unifitest.crosstalksolutions.com.
Click the green 'Create' button an your Droplet will be created. You will then be taken back to the dashboard where you can watch the Droplet creation progress. It only takes a few moments, and then you will receive an IP address for your Droplet.
Part 2 - Create a DNS A Record
Since you now know your IP address, you should log into your DNS hosting provider or DNS server and create a new A record that points the hostname that you created in Step 1 to the IP address of your Digital Ocean Droplet. This will be needed in the future when we create the secure SSL certificate for the UniFi Controller.
*** Digital Ocean Pro Tip ***
If you hover over your Droplet's IP address anywhere in the Digital Ocean dashboard or server details, a little 'copy' link pops up that lets you very easily copy the IP address to your clipboard.
Once your DNS A record has been created, you should be able to PING your hostname and receive the IP address of your Digital Ocean Droplet.
Part 3 - Log Into the Droplet with SSH
At this point, you should have received an email from Digital Ocean which contains your Droplet's IP address, username (which should be 'root') and password. Copy the password to your clipboard and then open up PuTTY.
Enter in the IP address or hostname of your Droplet and then click 'Open.'
PuTTY will open up a terminal window and first ask you if you want to accept the new host (click 'YES'). Then you will be given a login prompt. Use the information from the email that you received:
Password: (the password from the Digital Ocean email - you can do SHIFT+INS to paste it in)
The very first thing that you will be asked to do is to change your password. First, you need to enter in your current password that you received in the Digital Ocean email (it should already be on your clipboard, so you can do SHIFT+INS again to paste it in). Then you will have to enter a new password twice. Make sure you choose a very secure password for your root user.
Part 4 - Create New User
Most Linux machines in the world have root as the default user. The first line of defense is to create a separate login account with the same privileges and then disable root.
Start by creating a new user - for simplicity, for this exercise, our username will be 'unifiadmin':
This command will have you set a password for the new user, and you can also optionally enter in some additional information such as their real name and contact info.
Next give root (sudo group) privileges to the newly created user:
usermod -aG sudo unifiadmin
This new user will now be able to use the 'sudo' command to run commands as root.
At this point, we have created our new user, but we haven't yet disabled root - we will do that in a moment. First, we will enable private key authentication as a second line of defense.
Part 5 - Create Private Key Pair
Let's now create our public and private key pair. The public key lives on the server, and the private key will be used to unlock access from any device that needs it.
When asked where to put the file, take the default. You can choose whether or not to enter in a passphrase - having a passphrase means that you need both the private key and passphrase to gain access. It provides an additional layer of security.
Once your keys have been created, you will find them in /home/root/.ssh - there should be id_rsa (private key) and id_rsa.pub (public key) files in that directory.
Next, we need to copy that key to the newly created user's account:
ssh-copy-id unifiadmin@[server IP]
Choose 'yes' when asked if you want to continue, and enter unifiadmin's password when prompted.
This command will copy the public key to the unifiadmin user's ~/.ssh directory as an authorized_keys file. You can now use the private key to authenticate with this server as user unifiadmin.
Part 6 - Modify SSH Settings
The next step is to modify the SSH settings so that we will both disable root user access and password authentication. Start by editing the SSH configuration file:
nano -w /etc/ssh/sshd_config
Now scroll down until you find the line that says:
And change 'yes' to 'no':
This disables root user login. Next scroll down further and find:
And again change 'yes' to 'no':
This disables password based authentication. (Private key authentication should already be enabled by default - you can verify this by ensuring that PubkeyAuthentication is set to 'yes' in the SSH config file).
Press CTRL+X followed by 'Y' and 'Enter' to save and exit.
*** NOTE: This next command commits these changes. If you lose connectivity because you made any mistakes, you should just destroy the droplet and start over. ALSO - keep this original PuTTY session open as you go through the next few steps...even after we restart SSH, this session will still be connected, so if you can't connect in with the private key, you still have the opportunity to make changes.
Restart SSH with:
sudo systemctl reload sshd
Part 7 - Download Private Key File
Now we need to download our private key file. Start by showing the contents of the id_rsa file:
Select the entire contents of the file with your mouse and press CTRL+INS to copy the text to your clipboard.
Next, open up a text editor such as Notepad and paste the entire block of text into a blank file. Save this file in a secure location.
Part 8 - Covert Private Key to PuTTY format
Before you can use your private key with PuTTY, you need to convert it to .PPK format. To do this, we'll use another free program from the creators of PuTTY called PuTTYgen (you can download it from the same link as PuTTY above).
First, run PuTTYgen and click the 'Load' button. Browse to the private key file that you saved in step 7. When browsing for your private key, change the file type you are searching for from 'PuTTY Private Key Files (*.ppk)' to 'All Files (*.*).'
Open your private key file, and you should receive a notice that the private key was successfully imported. Click OK to get off of this notification.
Now, click the 'Save private key' button and save your private key as a .ppk file (I usually just use the same directory that I used to save the original private key). You can now close PuTTYgen.
Part 9 - Log in as New User
Start a new PuTTY session - you can do this from the existing window by clicking the PuTTY icon in the upper left-hand corner and choosing 'New Session.'
In the PuTTY window, enter the IP address or hostname of the server in the Host Name field.
Then, in the left-hand menu, expand the 'SSH' section underneath 'Connection.' Then click on 'Auth.' Here you will see a place to browse to your PuTTY .PPK private key file. Click 'Browse...' and find the .PPK file we created in step 8.
Once you have the file loaded, click back on 'Session' at the top of the left-hand menu.
If you want to SAVE these connection details, you should now enter in a friendly name into the 'Saved Sessions' box and click the 'Save.' button.
Now click 'Open,' and you should get a 'Login as:' prompt. Enter in the name of the user that you created in Part 4 and you should now connect to the server. If you have a passphrase on your private key pair, you will also be prompted for that passphrase.
Part 10 - Change SSH port
Now that we can log in with our secure key, let's take our SSH security even further by changing the default SSH port from 22 to something non-standard.
Edit the SSH config file again with:
sudo nano -w /etc/ssh/sshd_config
Find the line that says:
And change it to:
Port [different port number]
You can use any port number for your SSH connection, but I typcially use port 2222 when I change to something non-standard. CTRL+X followed by 'Y' and 'Enter' to save and exit Nano.
Restart SSH again with:
sudo systemctl reload sshd
Next, let's start a new PuTTY session using all of the same settings from Part 9, but this time also change the port to whichever port you changed SSH to. In our case, it was port 2222. If you previously saved your PuTTY session, you should save it again with the new port number.
Part 11 - Enable UFW Firewall
At this point, we have now secured our SSH connection pretty well. Now, let's secure our server even more by using some firewall rules to lock everything down.
Ubuntu uses the UFW firewall, however it is not enabled by default. First, we are going to add all of the firewall rules that we need to connect to UniFi, and then we will turn it on.
First, let's allow our new SSH port and lock it down so that connections to this port are only allowed from our IP address:
sudo ufw allow from [IP address] to any port [SSH port number]
In this example, if your IP address is 18.104.22.168, and your SSH port is 2222, the command should be:
sudo ufw allow from 22.214.171.124 to any port 2222
Next, let's open up access to the UniFi GUI. Important note here - you don't actually HAVE to open up this port to the outside world if you are instead using Ubiquiti's Single Sign On (SSO) account to access your UniFi Controller through https://unifi.ubnt.com. BUT - you will have to use this port at least once to enable cloud access in UniFi. You can either wait to do your firewall rules until after cloud access has been enabled, or you can disable this rule afterwards.
sudo ufw allow from [IP address] to any port 8443
Next, there are a couple of ports that we need open to the whole wide world. These are the STUN port and the UniFi inform port:
sudo ufw allow 3478/udp
sudo ufw allow 8080
Note that the STUN port running on 3478 is UDP.
If you are going to be using a guest portal with UniFi, you will also want to open these ports:
sudo ufw allow 8880
sudo ufw allow 8843
At this point, we will now turn on our UFW firewall and take a look at the rules that we created.
sudo ufw enable
When prompted whether or not to proceed, choose yes.
Let's take a look at our rules:
sudo ufw status
You should see something similar to this (note that I did not add the ports for guest portal access in my example):
The firewall is now running, and if you test your PuTTY connection again, you should still be able to connect. But - if you test connecting in on the standard SSH port 22, you will not be able to connect.
Part 12 - Update Server
Now that access to the server is secured, let's run our system updates.
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get dist-upgrade -y
It's possible that no updates will be needed, but if you are asked whether or not to proceed on any of these steps, just answer Y.
Part 13 - Install UniFi
There are a few different ways to download and install UniFi, but for me, the easiest way to install and maintain the UniFi package is to use apt, so that is what we will do in our example.
First, we need to add an apt source for UniFi. To do this, run the following commands:
echo 'deb http://www.ubnt.com/downloads/unifi/debian stable ubiquiti' | sudo tee /etc/apt/sources.list.d/100-ubnt-unifi.list
sudo wget -O /etc/apt/trusted.gpg.d/unifi-repo.gpg https://dl.ubnt.com/unifi/unifi-repo.gpg
These commands set up the apt repository for UniFi and install the trusted GPG key. Now let's install UniFi:
sudo apt-get update
sudo apt-get install -y unifi
You should now have installed the latest stable version of UniFi, which is version 5.6.29 as of the writing of this article.
Part 14 - UniFi Setup Wizard
Next, we need to go through the UniFi Setup Wizard.
Open a browser and connect to https://[server IP or FQDN]:8443.
You will be prompted with a warning screen that is warning you the site may be unsafe. This is because we have not yet installed our secure SSL certificate. Click through the warning, or just type 'badidea' if you're using Chrome to proceed. Note that sometimes, it can take up to 60 seconds before the setup wizard appears, so be patient.
Check your timezone and click 'Next.' Note that if you are restoring from backup, use the link on this page.
The next step is for configuring devices - at this stage, we don't have any devices to configure, and since this is a hosted server, any LAN devices you have plugged in would not be discovered anyway. Click Next to continue.
Here you can add a wireless network. For our purposes however, we are going to click 'skip' since this post does not deal with actual UniFi setup (see one of my many YouTube videos for that).
The next step is to choose a username and password for the UniFi admin account. I went with 'unifiadmin' as the user in order to match what we are using in SSH. For the password, note that it will not let you move forward to the next step until your password meets their strength requirements.
Click 'Next' when finished followed by 'Next' on the summary screen. You will then be asked if you want to set up your Ubiquiti Cloud Access:
You can enter in your cloud access account information if you have it, but if you don't have or don't know this information, you can always enable it later within UniFi.
Once you proceed or skip the UniFi cloud access setup, you will be redirected to the UniFi login screen. Log in with the credentials that you created during the setup wizard.
Part 15 - Install SSL Cert
Finally, we are going to install a secure certificate on our UniFi server. The SSL certificates that I use for my systems are from NameCheap.com. Now - you can use any SSL Certificate provider for installing your SSL Certificates - the instructions should be similar. But, if you want to do exactly what I am doing in this example, please click the link below to get your Positive SSL certification from NameCheap.com.
When you get to NameCheap.com, click on Security --> SSL Certificates. You don't need any of the more expensive certificates for this - the $9.00 PositiveSSL certificate will work just fine.
Click 'Buy Now' and add the certificate to the cart. Click 'Confirm Order' and complete the checkout process. When you go to the NameCheap dashboard, you will find your new certificate with an 'Activate' button. Click Activate to move to the next stage of the process.
When you click 'Activate,' you will be prompted to enter your CSR (Certificate Signing Request) - at this point, we need to go back to our UniFi server and generate the CSR. Log into the UniFi server as the user that you created above (unifiadmin in my example), and change directory to /usr/lib/unifi:
Next, run the following command to create your CSR file:
sudo java -jar lib/ace.jar new_cert unifi.mydomain.com “My Company Name” City State Country
For any part of this command where you have multiple words, you can enclose those words in double quotes. For example, if I wanted to create a certificate for Crosstalk Solutions LLC, located in New York, New York, USA, I would do:
sudo java -jar lib/ace.jar new_cert unifitest.crosstalksolutions.com “Crosstalk Solutions, LLC” "New York" NY US
Note that the state and country code are both 2 digits. If done correctly, you will be prompted for your sudo password, and then you will receive a message stating that your certificate has been generated. At this point, we need to copy and paste the contents of our certificate into NameCheap.com - but our user doesn't actually have permissions to view the directory where the cert was created, so first we need to switch to root:
Enter in your root password, and then do:
Once in the data directory, let's view the contents:
Here we should see a couple of files that were created - the one we want is the .pem file - it should be named unifi_certificate.csr.pem. Let's type out the contents of that file and then copy them into our clipboard:
Select all of the text that was output and type CTRL+INS to copy.
Now, go back to NameCheap.com and paste the contents of the .pem file into the 'Enter CSR' field. For server type, select 'Apache, Nginx, cPanel or other.'
Click 'Submit' to move to the next step. You should receive a screen that shows you the company, city, state, and country code that you used when you created the CSR file. Click 'Next' to continue.
Now we have a verification method - I find that email is the easiest verification method, but you can pick whichever one works best for your environment. Basically, what this means is that NameCheap has to verify that you own the domain (or have permission to purchase certs for the domain). In my case, I selected the Email method, and selected 'email@example.com' which happens to be our support email address. Once you finish going through this certificate wizard (we're on step 2 of 4), you will receive an email to the email address selected in the drop-down box. Inside that email will be a code and a link to click on - click the link and enter the code, and you'll be verified. But - we still have a couple of more steps in the wizard. Click 'Next' to continue.
In the next screen, we will enter in some company information - all information is optional except for Company Name, Address, City, State, and ZIP. Enter in all of that info, plus an administrative email address, and click 'Next.' On the final screen, you are given a summary to complete the wizard. Once the wizard is complete, you will be sent the SSL Certificate Validation email with the link and validation code to get your certificate validated (that is, assuming you chose the email validation method).
Once you have successfully validated, you can either log back into NameCheap.com and download your certificate file (see picture below), or you should also receive a copy in email.
The file that you receive will be a .ZIP file named as the FQDN that you are using for UniFi separated with underscores. In my case, my certificate file came to me as unifitest_crosstalksolutions_com.zip. Unzip that file onto your computer, and inside, you will find 3 files - one .crt file, one .p7b file, and one ca-bundle file. We will be using the .crt file and the ca-bundle file to import into UniFi. The first thing we need to do however is get these files onto our UniFi server. To do this, we're going to use WinSCP.
WinSCP is a free program that gives you a file explorer type of interface to other systems using SSH. Download and install WinSCP, and then create a new session for the UniFi server. Much like we did with PuTTY, we have to use port 2222, and we have to tell WinSCP where our .PPK private key file is.
First, click New Site. Use the following info:
File Protocol: SCP
Host Name: Your UniFi server FQDN (unifitest.crosstalksolutions.com in my example)
Port Number: Your SSH port number (2222 in my example)
User Name: The user name that you created in Part 4 (unifiadmin in my example)
Next, click on 'Advanced' and click on SSH --> Authentication. In the 'Private key file' box, browse to the .ppk private file that we used to connect with PuTTY in Part 9. Click OK once the file has been selected.
At this point, it is a good idea to save these settings in case you ever have to reconnect. Once saved, click 'Login' and you will be connected to your UniFi server. It should put you directly into your user's home directory, which is /home/unifiadmin in my case.
On the left hand side of the screen, browse for the certificate files that you unzipped and then drag and drop them over to the right hand side of the screen.
Now that our certificate files are on our UniFi server, we can close out WinSCP.
Go back to your PuTTY session, and let's import these certificates. If you haven't changed anything, then you should already be the root user - but if not, let's go ahead and switch to root before we do anything else:
Now, as root, run this command:
sudo java -jar lib/ace.jar import_cert /home/unifiadmin/unifitest_crosstalksolutions_com.crt /home/unifiadmin/unifitest_crosstalksolutions_com.ca-bundle
Unifiadmin should be changed to the user that you created in step 4 (or wherever you put the certificate files). And the file names you enter should be your own certificate file names. You do want to keep them in this order however with the .crt file before the .ca-bundle file.
If all goes well, you will receive a notice that your certificates were successfully imported, and that you should restart your UniFi Controller. Restart UniFi with:
service unifi restart
Once the UniFi service has been restarted, you can now close out your UniFi browser window and re-open it - you should now see a green 'Secure' certificate lock in the upper left-hand corner of the screen.
That's it! At this point, your hosted UniFi Control is about as secure as it can get, while still allowing devices to be adopted from anywhere in the world.
If you have any additional comments or questions, please comment below, and if you need UniFi setup assistance, contact Crosstalk Solutions at firstname.lastname@example.org.