UniFi Tutorials

Install UniFi Controller On Ubuntu 20.04 Linode

In this tutorial you will be shown how to install the UniFi Controller software with SSL on Ubuntu 20.04 using a Linode VPS.

The current version of UniFi SDN Controller that we will be installing is 6.2.23 Of course new packages will be released and they can be found on there UniFi Software Download Page. The script we will be using will install the latest version.

Linode VPS

Lets Get Started!

Prerequisites

  • Create a VPS server on Linode. The $10 plan meats minimum specifications and should be just fine up to 250 devices. You can even enable the option to create VPS backups witch is ideal.
  • To access the UniFi controller with a domain you will need to create an A record pointing to VPS server’s public IP address.

 

Getting Started With Linode

  1. Sign Up and Log into your Linode account and click the blue [Create Linode] button.
  2. The Distribution we will be selecting is Ubuntu 20.04 LTS.
  3. Select the best Region of yourself.
  4. Select the VPS plan you would like to use. 
  5. Give your server a Label. I will be giving it a FQDN label of unifi.patrickdomingues.com.
  6. Give it a secure root password. Click here to generate a password.
  7. Everything else you can skip but if you want to have backups check mark their backup box.
  8. Click the blue [Create Linode] button on the right to finish
  9. You should now see a page with details of your new Linode VPS.
  10. Now that you have your server IP address , create a name \ A record pointing to your server IP. 

Lets SSH into Ubuntu 20.04 and perform some updates.

  1. To SSH into the server we will be using Putty. Download and install Putty.
  2. Open up putty and type in the IPv4 address of your server and click open.
  3. Log into your Ubuntu 20.04 server with the username and password.
  4.  started with making sure we have the latest updates installed.
sudo apt update
sudo apt upgrade
sudo apt-get install ca-certificates wget -y

5. Give it a few minutes for the updates to install and afterwards run the following command to reboot.

reboot

Lets Install UniFi SDN Control Panel on Ubuntu 20.04

  1. Once the server is rebooted and your reconnected into the server using SSH we will now get started with running the following command. This script was created by Glenn and its very useful. 
rm unifi-latest.sh &> /dev/null; wget https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh && bash unifi-latest.sh

2. You will be prompted to keep the script which here I type in: Y
3. You will be prompted to apply some updates to the system, type in: Y
4. Now just wait while the installation proceeds to install some required software.
5. Next prompt will be to install script to be able to update Unifi Network Controller via APT, type in: Y
6. You should now be complete with the installation.
7. Lets make sure that the Unifi Controller service auto starts with the following command.

sudo systemctl enable unifi

8. We will now configure a proper firewall with rules for your Ubuntu 20.04 Server. We will be using the simple ot use ufw firewall. Before we turn on the firewall lets add some ports to the firewall rules.

sudo ufw allow 22
sudo ufw allow 8080
sudo ufw allow 8880
sudo ufw allow 8443
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 3478/udp
sudo ufw allow 10001/udp
sudo ufw allow 6666/udp
sudo ufw allow 47763/udp

9. Now that we have the rules in place we can enable the ufw firewall and set it to auto start.

sudo systemctl enable ufw
sudo ufw enable

At this point the controller is up and running and properly configured on the firewall and server. Lets move forward with configuring SSL certificate for your domain!

Install SSL Certificate For Your Domain To Access Unifi Controller

  1. To start we will need to install LetsEncrypt
sudo apt-get update 
sudo apt-get install letsencrypt

2. Run the following command to generate a SSL Certificate for your domain. Please change the domain so it reflects your domain.

sudo letsencrypt certonly

3. Now lets download a script that will do the majority of the work for you to import the SSL Certificate into the Unifi Controller. 

sudo wget https://raw.githubusercontent.com/stevejenkins/unifi-linux-utils/master/unifi_ssl_import.sh -O /usr/local/bin/unifi_ssl_import.sh

4. Lets change the Permission of the script using the following command

sudo chmod +x /usr/local/bin/unifi_ssl_import.sh

6. With these following steps we will be editing the script to use your domain.

sudo nano -w /usr/local/bin/unifi_ssl_import.sh

Within this text view locate and change the following.

Add your domain
UNIFI_HOSTNAME=unifi.yourdomain.com

Comment the three lines for Fedora/RedHat/Centos by placing a # for it:
#Uncomment following three lines for Fedora/RedHat/CentOS
#UNIFI_DIR=/opt/UniFi
#JAVA_DIR=${UNIFI_DIR}
#KEYSTORE=${UNIFI_DIR}/data/keystore

Uncomment the three lines for Debian/Ubuntu
# Uncomment following three lines for Debian/Ubuntu
UNIFI_DIR=/var/lib/unifi
JAVA_DIR=/usr/lib/unifi
KEYSTORE=${UNIFI_DIR}/keystore


Set the Let’s Encrypt mode to yes:
If you only enable the line, by removing the #, and you will have to set the value to yes.
LE_MODE=yes

Save and close the file
Press Ctrl +X followed by Y and Enter to save and close the file.

7. Now lets run the script to import the SSL cert info the Unifi Controller.

sudo /usr/local/bin/unifi_ssl_import.sh

8. We will now create a script to auto renew the SSL cert for you. Run the following command to create a new file.

sudo nano -w /etc/crontab

And add the following content into it
0 */12 * * * root letsencrypt renew
5 */12 * * * root unifi_ssl_import.sh
Press Ctrl +X followed by Y and Enter to save and close the file.

 

Installing Fail2ban

Fail2ban will protect your cloud hosted Unifi Controller from brute force attacks. This script will ban people after 4 failed attempts for 10 minutes. 

rm unifi-fail2ban.sh &> /dev/null; wget https://get.glennr.nl/unifi/extra/unifi-fail2ban.sh && bash unifi-fail2ban.sh

All Done! You should now have a 100% working SSL protected Unifi Controller installed on Ubuntu 20.04 hosted on a Linode VPS.

I hope this article was helpful, if you have any questions, please feel free to contact me. If you would like to be notified of when I create a new post, you can subscribe to my blog alert.


Discover more from Patrick Domingues

Subscribe to get the latest posts sent to your email.

author avatar
Patrick Domingues

13 Comments

  1. Hi Patrick, thanks for sharing your work, I wanted to ask, after setup the controller following your guide, how do you add devices in the different location you may have? Need to create vpn to sites, or how do I manage to point the devices to the fqdn address. Thanks in advance for your answer.

    1. There are a few things that we will need and the only firewalls that can be adopted into a Unifi cloud controller at the moment are USG https://www.ui.com/unifi-routing/usg/ and the USG-Pro-4 https://www.ui.com/unifi-routing/unifi-security-gateway-pro-4/ . The UDM-PRO cannot be adopted onto a cloud controller you would have to use the onboard controller and access this devices from the unifi.ui.com portal. Now this being said if you are using the USG or USG-Pro within the cloud hosted controller you will have to create two sites each site will have 1 firewall adopted into each. Now this being said log into your Cloud hosted controller and on the top right you will see current site. If you click on that you will get a drop down, select add new site. Once that’s created adopt a firewall in there and one firewall in the default unless you want to create a named site for both locations. Unfortunately you can only use ip-addresses for site to site vpns. However Client (computer) vpn to firewall vpn you can use FQDN. Providing this video will be easier to follow than me explaining it https://www.youtube.com/watch?v=g2wXjV6xjMg . Its a great idea for me to have a write up and a video tutorial so I will have one done shortly. I hope this helps, if you have more questions let me know and thank you for the visit!

  2. Patrick,
    Thanks for the information you have posted here. I am on the final step of deploying a new ubuntu 20.04 server for my home automation: configuring wifi. My client machine works fine when I am connected via Ethernet. When I move from the cable to my wap, a UAP-AC-HC firmware 5.43.52, I am no longer able to get out to the internet. I have applied the firewall rules you mention in this post.

    Here are my firewall rules and iptable entries
    To Action From
    — —— —-
    22/tcp ALLOW Anywhere
    80/tcp ALLOW Anywhere
    443/tcp ALLOW Anywhere
    19999/tcp ALLOW Anywhere
    8443/tcp ALLOW Anywhere
    8123/tcp ALLOW Anywhere
    1880/tcp ALLOW Anywhere
    OpenSSH ALLOW Anywhere
    22/udp ALLOW Anywhere
    53/tcp ALLOW Anywhere
    53/udp ALLOW Anywhere
    22 ALLOW Anywhere
    8080 ALLOW Anywhere
    8880 ALLOW Anywhere
    8443 ALLOW Anywhere
    80 ALLOW Anywhere
    443 ALLOW Anywhere
    3478/udp ALLOW Anywhere
    10001/udp ALLOW Anywhere
    6666/udp ALLOW Anywhere
    47763/udp ALLOW Anywhere
    Anywhere ALLOW 192.168.15.0/24
    8880/udp ALLOW Anywhere
    8843/udp ALLOW Anywhere
    6789/tcp ALLOW Anywhere
    1900/udp ALLOW Anywhere
    5514/udp ALLOW Anywhere
    9080/tcp ALLOW Anywhere
    22/tcp (v6) ALLOW Anywhere (v6)
    80/tcp (v6) ALLOW Anywhere (v6)
    443/tcp (v6) ALLOW Anywhere (v6)
    19999/tcp (v6) ALLOW Anywhere (v6)
    8443/tcp (v6) ALLOW Anywhere (v6)
    8123/tcp (v6) ALLOW Anywhere (v6)
    1880/tcp (v6) ALLOW Anywhere (v6)
    OpenSSH (v6) ALLOW Anywhere (v6)
    22/udp (v6) ALLOW Anywhere (v6)
    53/tcp (v6) ALLOW Anywhere (v6)
    53/udp (v6) ALLOW Anywhere (v6)
    22 (v6) ALLOW Anywhere (v6)
    8080 (v6) ALLOW Anywhere (v6)
    8880 (v6) ALLOW Anywhere (v6)
    8443 (v6) ALLOW Anywhere (v6)
    80 (v6) ALLOW Anywhere (v6)
    443 (v6) ALLOW Anywhere (v6)
    3478/udp (v6) ALLOW Anywhere (v6)
    10001/udp (v6) ALLOW Anywhere (v6)
    6666/udp (v6) ALLOW Anywhere (v6)
    47763/udp (v6) ALLOW Anywhere (v6)
    8880/udp (v6) ALLOW Anywhere (v6)
    8843/udp (v6) ALLOW Anywhere (v6)
    6789/tcp (v6) ALLOW Anywhere (v6)
    1900/udp (v6) ALLOW Anywhere (v6)
    5514/udp (v6) ALLOW Anywhere (v6)
    9080/tcp (v6) ALLOW Anywhere (v6)

    # Generated by iptables-save v1.8.4 on Thu Dec 23 20:07:24 2021
    *nat
    :PREROUTING ACCEPT [1295:112217]
    :INPUT ACCEPT [739:57570]
    :OUTPUT ACCEPT [126:8077]
    :POSTROUTING ACCEPT [75:4620]
    -A POSTROUTING -o enp1s0 -j MASQUERADE
    COMMIT
    # Completed on Thu Dec 23 20:07:24 2021
    # Generated by iptables-save v1.8.4 on Thu Dec 23 20:07:24 2021
    *filter
    :INPUT DROP [153:9095]
    :FORWARD DROP [1:344]
    :OUTPUT ACCEPT [4:168]
    :ufw-after-forward – [0:0]
    :ufw-after-input – [0:0]
    :ufw-after-logging-forward – [0:0]
    :ufw-after-logging-input – [0:0]
    :ufw-after-logging-output – [0:0]
    :ufw-after-output – [0:0]
    :ufw-before-forward – [0:0]
    :ufw-before-input – [0:0]
    :ufw-before-logging-forward – [0:0]
    :ufw-before-logging-input – [0:0]
    :ufw-before-logging-output – [0:0]
    :ufw-before-output – [0:0]
    :ufw-logging-allow – [0:0]
    :ufw-logging-deny – [0:0]
    :ufw-not-local – [0:0]
    :ufw-reject-forward – [0:0]
    :ufw-reject-input – [0:0]
    :ufw-reject-output – [0:0]
    :ufw-skip-to-policy-forward – [0:0]
    :ufw-skip-to-policy-input – [0:0]
    :ufw-skip-to-policy-output – [0:0]
    :ufw-track-forward – [0:0]
    :ufw-track-input – [0:0]
    :ufw-track-output – [0:0]
    :ufw-user-forward – [0:0]
    :ufw-user-input – [0:0]
    :ufw-user-limit – [0:0]
    :ufw-user-limit-accept – [0:0]
    :ufw-user-logging-forward – [0:0]
    :ufw-user-logging-input – [0:0]
    :ufw-user-logging-output – [0:0]
    :ufw-user-output – [0:0]
    -A INPUT -i lo -j ACCEPT
    -A INPUT -i enp2s0 -j ACCEPT
    -A INPUT -i enp1s0 -m conntrack –ctstate RELATED,ESTABLISHED -j ACCEPT
    -A INPUT -j ufw-before-logging-input
    -A INPUT -j ufw-before-input
    -A INPUT -j ufw-after-input
    -A INPUT -j ufw-after-logging-input
    -A INPUT -j ufw-reject-input
    -A INPUT -j ufw-track-input
    -A FORWARD -i enp2s0 -o enp1s0 -j ACCEPT
    -A FORWARD -i enp1s0 -o enp2s0 -m conntrack –ctstate RELATED,ESTABLISHED -j ACCEPT
    -A FORWARD -j ufw-before-logging-forward
    -A FORWARD -j ufw-before-forward
    -A FORWARD -j ufw-after-forward
    -A FORWARD -j ufw-after-logging-forward
    -A FORWARD -j ufw-reject-forward
    -A FORWARD -j ufw-track-forward
    -A OUTPUT -j ufw-before-logging-output
    -A OUTPUT -j ufw-before-output
    -A OUTPUT -j ufw-after-output
    -A OUTPUT -j ufw-after-logging-output
    -A OUTPUT -j ufw-reject-output
    -A OUTPUT -j ufw-track-output
    -A ufw-after-input -p udp -m udp –dport 137 -j ufw-skip-to-policy-input
    -A ufw-after-input -p udp -m udp –dport 138 -j ufw-skip-to-policy-input
    -A ufw-after-input -p tcp -m tcp –dport 139 -j ufw-skip-to-policy-input
    -A ufw-after-input -p tcp -m tcp –dport 445 -j ufw-skip-to-policy-input
    -A ufw-after-input -p udp -m udp –dport 67 -j ufw-skip-to-policy-input
    -A ufw-after-input -p udp -m udp –dport 68 -j ufw-skip-to-policy-input
    -A ufw-after-input -m addrtype –dst-type BROADCAST -j ufw-skip-to-policy-input
    -A ufw-after-logging-forward -m limit –limit 3/min –limit-burst 10 -j LOG –log-prefix “[UFW BLOCK] ”
    -A ufw-after-logging-input -m limit –limit 3/min –limit-burst 10 -j LOG –log-prefix “[UFW BLOCK] ”
    -A ufw-before-forward -m conntrack –ctstate RELATED,ESTABLISHED -j ACCEPT
    -A ufw-before-forward -p icmp -m icmp –icmp-type 3 -j ACCEPT
    -A ufw-before-forward -p icmp -m icmp –icmp-type 11 -j ACCEPT
    -A ufw-before-forward -p icmp -m icmp –icmp-type 12 -j ACCEPT
    -A ufw-before-forward -p icmp -m icmp –icmp-type 8 -j ACCEPT
    -A ufw-before-forward -j ufw-user-forward
    -A ufw-before-input -i lo -j ACCEPT
    -A ufw-before-input -m conntrack –ctstate RELATED,ESTABLISHED -j ACCEPT
    -A ufw-before-input -m conntrack –ctstate INVALID -j ufw-logging-deny
    -A ufw-before-input -m conntrack –ctstate INVALID -j DROP
    -A ufw-before-input -p icmp -m icmp –icmp-type 3 -j ACCEPT
    -A ufw-before-input -p icmp -m icmp –icmp-type 11 -j ACCEPT
    -A ufw-before-input -p icmp -m icmp –icmp-type 12 -j ACCEPT
    -A ufw-before-input -p icmp -m icmp –icmp-type 8 -j ACCEPT
    -A ufw-before-input -p udp -m udp –sport 67 –dport 68 -j ACCEPT
    -A ufw-before-input -j ufw-not-local
    -A ufw-before-input -d 224.0.0.251/32 -p udp -m udp –dport 5353 -j ACCEPT
    -A ufw-before-input -d 239.255.255.250/32 -p udp -m udp –dport 1900 -j ACCEPT
    -A ufw-before-input -j ufw-user-input
    -A ufw-before-output -o lo -j ACCEPT
    -A ufw-before-output -m conntrack –ctstate RELATED,ESTABLISHED -j ACCEPT
    -A ufw-before-output -j ufw-user-output
    -A ufw-logging-allow -m limit –limit 3/min –limit-burst 10 -j LOG –log-prefix “[UFW ALLOW] ”
    -A ufw-logging-deny -m conntrack –ctstate INVALID -m limit –limit 3/min –limit-burst 10 -j RETURN
    -A ufw-logging-deny -m limit –limit 3/min –limit-burst 10 -j LOG –log-prefix “[UFW BLOCK] ”
    -A ufw-not-local -m addrtype –dst-type LOCAL -j RETURN
    -A ufw-not-local -m addrtype –dst-type MULTICAST -j RETURN
    -A ufw-not-local -m addrtype –dst-type BROADCAST -j RETURN
    -A ufw-not-local -m limit –limit 3/min –limit-burst 10 -j ufw-logging-deny
    -A ufw-not-local -j DROP
    -A ufw-skip-to-policy-forward -j DROP
    -A ufw-skip-to-policy-input -j DROP
    -A ufw-skip-to-policy-output -j ACCEPT
    -A ufw-track-output -p tcp -m conntrack –ctstate NEW -j ACCEPT
    -A ufw-track-output -p udp -m conntrack –ctstate NEW -j ACCEPT
    -A ufw-user-input -p tcp -m tcp –dport 19999 -j ACCEPT
    -A ufw-user-limit -m limit –limit 3/min -j LOG –log-prefix “[UFW LIMIT BLOCK] ”
    -A ufw-user-limit -j REJECT –reject-with icmp-port-unreachable
    -A ufw-user-limit-accept -j ACCEPT
    COMMIT
    # Completed on Thu Dec 23 20:07:24 2021

    Any debugging tips that you might be able to offer would be most helpful,

    Thanks in advance,

    Frederick

  3. Dear Patrick,

    Thank you for your great tutorial! Sadly enough I end up with a “http status 404 not found” error. I followed your tutorial to the letter. Installed everything on a new Ubuntu 20.04 LTS VPS and only had to install nano and ufw which wasn’t active. Didn’t get any errors during the installation of everything that is mentioned in this tutorial. I rebooted but the result stays the same.

    Do you have any tips for me to check?

    Thanks,

    Stef

    1. Hello Stef,

      Did you happen to install this on Linode or somewhere else? Is the Unifi service running? Are you behind another firewall? Have you double checked all ports are open?

  4. Hi Patrick,

    Thanks for responding. No I used a different VPS service. The Unifi service is active. The only firewall is the one I installed with ufw in the tutorial. All ports are open. I am suspecting that something is wrong with Java. The Network Controller application fails to start somehow. Could it be that the latest Unifi release needs a newer Java release?

    Regards,

    Stef

  5. Hello,

    I followed your tutorial, and the controller works fine, but I can only access it by Linode’s public IP address without SSL. I address A record for my domain after creating a subdomain. What do you think the issue is?

    1. Start with the following and follow the wizard. Made sure to download a backup config just in case.
      rm unifi-latest.sh &> /dev/null; wget https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh && bash unifi-latest.sh

Leave a Comment

Stay Informed

Receive instant notifications when new content is released.