Unifi Controller on Hetzner Cloud with Ubuntu
Last updated: 2. December 2022
This guide describes how to set up a hosted Unifi Controller application for managing Ubiquiti Unifi products on a Hetzner Cloud server based on Ubuntu 20.04.
The Unifi Controller application is based on Java and uses MongoDB as well as the file system (/var/lib/unifi/
) for data storage.
Rationale for self-hosting
Advantages:
- Access the controller from everywhere, no DynDNS / port forwarding / firewall rules required in your network.
- No need to use the UniFi Portal (but the controller can be added there, if desired).
- No need to use a Ubiquiti cloud account.
- Easy to get a valid SSL certificate for controller GUI and captive/hotspot portal.
- Multi-site support (no longer available on Cloud Key Gen2 since recent firmware updates).
Disadvantages:
- Device adoption requires Layer-3-Adoption, i.e. needs either specific configuration of the local DNS/DHCP server, a browser plugin, smartphone app, or manually setting the controller URL per device.
- Slightly longer device adoption times.
- Slight delay in captive/guest hotspot portal access.
Requirements
- Hetzner Cloud account
- (Sub)domain name which can be used to access the controller, in this article we’ll use
unifi.example.com
- SSH key, needed to connect to the cloud server once its up and running
Setting up the server in Hetzner Cloud
Login to the Hetzner cloud console and create a new Project (e.g. Ubiquiti), if necessary.
SSH Key
Make sure you have registered an SSH key in the project security settings.
Floating IP
Create a new floating IP address (in this article we’ll use 198.51.100.123
as an example). Make sure that the IP address and the server you create later are located in the same data centre.
Set unifi.example.com
as the reverse DNS (rDNS) entry of the floating IP.
Head over to the DNS management service of your domain name (e.g. Hetzner DNS) and add a new A-Record for unifi.example.com
, which points to the newly obtained IP address.
Server
Create a new server in the Cloud console:
- Location (same as floating IP)
- Image: Ubuntu 20.04
- Type: CX11 (Standard, local NVMe SSD, 1 vCPU, 2 GB RAM, 20 GB SSD)
- Volume: (none)
- Network: (none)
- User data: (none)
- Backup: recommended
- Name: unifi
Once the server has been created, assign floating IP address to this server.
Login to the server via SSH, using username root
and your SSH key.
Note that for the first login, you have to use the auto-generated server IP address, as the floating IP has not yet been configured on the server (see next step).
Configuring the network
Add the floating IP address to the network settings, by creating the file /etc/netplan/60-floating-ip.yaml
and editing it using the Nano editor:
touch /etc/netplan/60-floating-ip.yaml
nano /etc/netplan/60-floating-ip.yaml
Add the following content (replace the IP with your actual floating IP address):
network:
version: 2
ethernets:
eth0:
addresses:
- 198.51.100.123/32
Hit Ctrl+x to exit Nano.
Apply the new network settings:
netplan apply
Also, set the hostname of the system:
hostnamectl set-hostname unifi.example.com
Software installation
Update the system packages and install some necessary utilities:
apt update && apt upgrade -y
apt install -y ca-certificates apt-transport-https
Add the Unifi APT package repository and the related GPG key:
echo 'deb https://www.ui.com/downloads/unifi/debian stable ubiquiti' | tee /etc/apt/sources.list.d/100-ubnt-unifi.list
wget -O /etc/apt/trusted.gpg.d/unifi-repo.gpg https://dl.ui.com/unifi/unifi-repo.gpg
apt update
Prevent the package manager from installing Java versions above 8, as the Unifi Controller still relies on Java 8:
apt-mark hold openjdk-11-*
apt-mark hold openjdk-13-*
apt-mark hold openjdk-14-*
apt-mark hold openjdk-16-*
apt-mark hold openjdk-17-*
Install the Unifi Controller, the haveged Entropy daemon, and the Let’s Encrypt certbot:
apt install -y unifi haveged certbot openjdk-8-jre-headless
Haveged adds additional entropy (randomness) to the system random number generator. This is needed on virtual machines, as they might not provide enough entropy required by certain encryption-related functions.
Check that both the unifi
and haveged
services are running:
service unifi status
service haveged status
In case of a problem, you can view the latest log entries of a service, e.g. unifi
, like this:
journalctl -u unifi -n 50
The Unifi controller log files can be found in /usr/lib/unifi/logs
.
Adding a valid SSL certificate
Request a Let’s Encrypt certificate for your system:
certbot certonly --standalone -d unifi.example.com
Note: This requires that your domain name can be resolved to your floating IP address. Depending on the TTLs of the involved DNS servers, this might take a while to become active.
The Unifi controller is a Java application, and its SSL keys are stored in the associated Java Keystore file. Therefore, the keys created by certbot need to be imported into that keystore. This can be achieved by using e.g. Steve Jenkins’ Unifi SSL Import script:
wget https://raw.githubusercontent.com/stevejenkins/unifi-linux-utils/master/unifi_ssl_import.sh -O /usr/local/bin/unifi_ssl_import.sh
chmod +x /usr/local/bin/unifi_ssl_import.sh
Edit the file with Nano:
nano /usr/local/bin/unifi_ssl_import.sh
and make sure to change the following variables:
UNIFI_HOSTNAME=unifi.example.com
UNIFI_DIR=/var/lib/unifi
JAVA_DIR=/usr/lib/unifi
KEYSTORE=${UNIFI_DIR}/keystore
LE_MODE=true
Run the script:
/usr/local/bin/unifi_ssl_import.sh
Make it run on a daily basis:
ln -s /usr/local/bin/unifi_ssl_import.sh /etc/cron.daily/unifi_ssl_import
Access the web UI
Open https://unifi.example.com:8443 in your browser and complete the first-run wizard to setup your controller.
If you choose to enable remote access and link the controller to the UniFi Cloud Portal, the controller will show up in the legacy variant of the portal, the UniFi Network Portal.
To adopt your Unifi devices into this controller, follow the procedure outlined in the Ubiquiti Support and Help Center. Use your floating IP address (e.g. 198.51.100.123
) to set the controller URL, or set the inform URL as e.g. http://198.51.100.123:8080/inform or http://unifi.example.com:8080/inform
Firewall configuration
Whitelist ports
Configure either the system firewall (using iptables or ufw) or the Hetzner Cloud Firewall to only allow the necessary ports, and allow access only from known source network addresses.
GUI port forwarding
For convenience, you can add firewall redirects from port 80 to 8080 (HTTP) and from port 443 to 8443 (HTTPS), so you can omit adding the port number to the URL when using the web GUI.
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8443
ip6tables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
ip6tables -A PREROUTING -t nat -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8443
apt install -y iptables-persistent
Make sure access to ports 80 and 443 is allowed by the ingress firewall.
Open https://unifi.example.com in your browser to verify the setup.
Alternatively, you can install nginx or apache web server to create redirects.
Installing a specific version of the controller
The above instructions make use of the Ubiquiti APT repository, which will provide the latest “stable” package. If you want to install and stay on a specific version of the controller, you have to omit the package repository and download the package manually.
Find the URL of the desired package on the Ubiquiti Download Portal. Look for entries of the form “UniFi Network Controller x.y.z for Debian/Ubuntu Linux and UniFi Cloud Key”.
In this example we are going to use version 6.0.45, since this is the last version as of writing this article.
Download the package:
cd /tmp
wget https://dl.ui.com/unifi/6.0.45/unifi_sysvinit_all.deb
Attempt installation:
dpkg -i unifi_sysvinit_all.deb
This command might abort, mentioning missing dependencies. Not a problem, just run:
apt install -f
and the installation should complete. To finish, remove the package file:
rm unifi_sysvinit_all.deb*
In case you want to update the package, make sure you have a backup of the configuration, then download the desired version with wget
and run:
dpkg -i unifi_sysvinit_all.deb
Uninstalling the software
If you want to remove the Unifi software and all configuration (e.g. for a fresh start), run:
apt-get remove --purge unifi
References
- https://help.ui.com/hc/en-us/articles/220066768-UniFi-How-to-Install-and-Update-via-APT-on-Debian-or-Ubuntu
- https://lazyadmin.nl/home-network/unifi-controller-ssl-certificate/
- https://help.ui.com/hc/en-us/articles/209376117-UniFi-Install-a-UniFi-Cloud-Controller-on-Amazon-Web-Services
- https://gist.github.com/danibram/d00ed812f2ca6a68758e