Skip to content

Instantly share code, notes, and snippets.

@rma92
Last active May 9, 2024 20:11
Show Gist options
  • Save rma92/e2e3752c56f9b86840b4696b870e5ecd to your computer and use it in GitHub Desktop.
Save rma92/e2e3752c56f9b86840b4696b870e5ecd to your computer and use it in GitHub Desktop.
Unifi controller on OpenBSD using Ports

The Unifi controller is in OpenBSD's ports tree, so you can simply install it from there.

However, due to the odd amount of space required to build it, you may want to install the whole system on a single partiton, assuming this is a single purpose system that we can back up.

Installing OpenBSD

Install OpenBSD normally until you get to the disk set up. Use the (W) Whole Disk, but set a custom layout (c).

  • Enter "a " to add a partition.
  • Use the default offset, size, and fs type ( 3 times).
  • Mount point should be "/" .
  • w [Write]
  • q [Quit fdisk] Continue installing sets as normal.

Setting up the system - sudo

(You may want to use doas or just su, my environments sometimes require sudo specifically)

Log in as root, or log in as yourself and run su to become root.

pkg_add portslist sudo--
echo "%wheel ALL=(ALL) ALL" | EDITOR='tee -a' visudo

Add your user to group 'wheel'

usermod -G wheel <username>

Logout as root or exit su.

Set up ports

As your normal user:

cd /tmp
ftp https://cdn.openbsd.org/pub/OpenBSD/$(uname -r)/{ports.tar.gz,SHA256.sig}
signify -Cp /etc/signify/openbsd-$(uname -r | cut -c 1,3)-base.pub -x SHA256.sig ports.tar.gz

As root (sudo -s, sudo su, or su):

cd /usr
tar xzf /tmp/ports.tar.gz

Type exit to return to your normal account.

Build and install the latest Unifi controller

cd /usr/ports/net/unifi/main
sudo -s
make FETCH_PACKAGES= install

This should take a few minutes. The FETCH_PACKAGES= is optional, but will result in checking that packages exist rather than building things that are already packaged as binaries. Note there is a space after the equals sign. Once this is done, you can start the controller and go to https://<IP Address>:8443/ in a browesr (not putting the trailing / resulted in a 404).

(This took less than 7 minutes on a vultr CPU-optimized instance)

rcctl start unifi

If you are setting up for paranoia:

  • Name the application and click Next
  • Click Advanced Setup.
  • Uncheck the two options (Enable Remote Access, Use your Ubiquiti account for local access)
  • Set a local username and password, click next.
  • The auto-backup does not use cloud, it creates them in a folder on the system. I'd turn this on.
  • You can skip adoption if you want (cloud adoption requires additional setup), or adopt devices now.

Reference: Performance

  • It took less than 7 minutes from clicking Deploy in the Vultr control panel to having a working install on a Vultr $28/mo CPU Optimized Instance (I used a large instance for testing - this is excesssive for something this low throughput)
  • df -h on the server with OpenBSD 7.4 (without cleanup or compression):
vultr$ df -h .
Filesystem     Size    Used   Avail Capacity  Mounted on
/dev/sd0a     21.3G    3.6G   16.6G    18%    /
vultr$ uname -a
OpenBSD vultr.guest 7.4 GENERIC.MP#1396 amd64
  • Memory usage: System was using 586MB (2GB available). It can probably use less if the system is smaller. image

Reference: Searching ports

(Optional, but for reference) To search the ports:

cd /usr/ports
make search key=unifi

(make the key whatever you want to search for in the ports tree)

Cloud - pf firewall

The firewall shoupd be configured appropriately. I used the following pf to allow the Unifi device ports from anywhere (temporarily) and allow access to the console only from my IP address.

  • It may be better to access the console only over SSH.
  • Some of the sites have dynamic IP addresses, so setting up a firewall for this is not immediately straightforward. Ideally, the controller would be accessed over a VPN it seems.
set skip on lo

#anti lockout
pass in quick proto tcp from any to any port 22

block all
block return    # block stateless traffic
#pass           # establish keep-state, default pass
pass out quick proto { tcp, udp } from any to { 8.8.8.8, 1.1.1.1 } port domain

# Allow anything from my IP addresses
pass in proto {icmp, tcp, udp}  from { 136.28.2.0/23 209.200.230.0/24 } to any

# Allow ICMP
pass in inet proto icmp icmp-type echoreq

# Allow Unifi ports - Device configuration (8080) and speed test (6789)
pass in proto tcp from any to any port { 8080, 6789 }

# Allow STUN - no use if there's no Unifi router.
# pass in proto udp from any to any port { 3478 }

# Allow Unifi ports - portal redirection
#pass in proto tcp from any to any port { 8880, 8843 }

# Unifi: NTP
pass out proto udp from any to any port 123
pass in proto udp from any to any port 123

# By default, do not permit remote connections to X11
block return in on ! lo0 proto tcp to port 6000:6010

# Port build user does not need network
block return out log proto {tcp udp} user _pbuild

Adopting in the cloud - DHCP

This is really easy if you have an EdgeRouter - go to Services > DHCP Server > Actions (drop-down for the relevant subnet) > Details There's a field for Unifi Controller. Enter the hostname or IP address of the Unifi controller.

If you're using a different DHCP server, it's DHCP Option 43.

See: https://help.ui.com/hc/en-us/articles/204909754-UniFi-Network-UniFi-Cloud-Adoption-Layer-3-

To test connectivity from the network, accessing http://:8080/inform should cause an HTTP 400 (instead of 404).

Attempt at a hardened one on OpenBSD on Vultr

  • Upload install.iso for OpenBSD to Vultr, create a new VM using the ISO. You need the ISO to create full disk encryption. Also this eliminates any potential security issues cloud-init can cause.
  • Set a full disk encryption key, set a root password that is strong, set a user that doesn't match anyone's name with a good password.
  • Start sshd by default, don't allow root logins.
  • Install the entire system to a single / partition (for disk usage reasons)

Each time the VM boots, someone will need to manually enter the encryption key at the prompt.

Initial setup: enable doas, change SSH port, pubkey auth only

Enable doas

  • Become root.
su
  • Set up doas for the user.
echo "permit user1" | tee -a /etc/doas.conf
usermod -G wheel user1

Change SSH port

(As root, which should now be accessible via doas)

vi /etc/ssh/sshd_config

Write Port 24601 (or whatever port you want, save the file)

Allow the traffic in pf

vi /etc/pf.conf

Add:

pass in quick on egress proto tcp from any to any port 24601

Then use pfctl -nf /etc/pf.conf to check for errors. If everything is good:

pfctl -f /etc/pf.conf
pfctl -e
rcctl restart sshd

Pubkey Auth Only

Edit /etc/ssh/sshd_config and set:

PasswordAuthentication no
PubkeyAuthentication yes

pf

Make the system hard, uncomment unifi parts as needed, fix or not use known networks:

set block-policy drop
pass out quick proto { tcp, udp } from any to { 108.61.10.10 8.8.8.8, 1.1.1.1 } port domain
pass in quick on egress proto tcp from any to any port 52209

#Browser
#pass out quick on egress proto tcp to any port { 80, 443 }

icmp_types = "echoreq"
pass quick inet proto icmp all icmp-type $icmp_types

#Unifi: uncomment as needed
known_networks = "{ 136.28.2.0/23 209.200.230.0/24 }"

# Allow Unifi ports - Device configuration (8080) and speed test (6789)
#pass in proto tcp from any to any port { 8080, 6789 }
pass in proto tcp from $known_networks to any port { 8080, 6789 }

# Allow STUN - no use if there's no Unifi router.
# pass in proto udp from any to any port { 3478 }

# Allow Unifi ports - portal redirection
#pass in proto tcp from any to any port { 8880, 8843 }

#End Unifi

set skip on lo
block in all

Make the system hard (no unifi):

set block-policy drop
pass in quick on egress proto tcp from any to any port 52209
dns_servers = "{ 108.61.10.10 8.8.8.8 8.8.4.4 }"
pass in quick on any proto { udp, tcp } from any to { $dns_servers } port 53
pass out quick on any proto { udp, tcp} from ant to { $dns_servers } port 53
#Web Browser Outbound
#pass out quick on egress proto tcp to any port { 80, 443 }

icmp_types = "echoreq"
pass quick inet proto icmp all icmp-type $icmp_types

set skip on lo
block in all

Ancient OpenBSD on small footprint

(This is bad for security, don't do this outside of a lab)

6.1 had a tiny disk footprint. Old mirrors can be found at: http://ftp.lysator.liu.se/pub/OpenBSD/6.1/

When you install the system, echo 'http://ftp.lysator.liu.se/pub/OpenBSD' > /etc/installurl (note https will have cert issues until you fix the certificates)

If the computer is too slow or small (<48MB RAM) and we don't care about security, disable reodering libraries (edit /etc/rc, comment out the call to reorder_libs by putting a # in front of it)

rcctl disable smtpd
rcctl disable ntpd
rcctl disable syslogd
rcctl disable pflogd
rcctl disable sndiod

Making a package file to install on another system

After the software has been built in ports, you can make a package so you don't have to build it for another system.

cd /usr/ports/net/unfi/main
make package
cd  /usr/ports/packages/amd64/all/

SCP the files to the new system.

pkg_add -D unsigned unifi-7.4.162.tgz
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment