I've been one of DD-WRT's biggest fans, for more than 10 years. I've always flashed my router with custom firmware, fine-tuned my wired and wireless networks, and locked down a VPN back home. I've genuinely always loved tinkering with network gear.
A couple of weeks ago, I decided to re-deploy my home network. I've been hearing about Ubiquiti Networks from my colleagues at Canonical, where we use Ubiquiti gear for our many and varied company events. Moreover, it seems a number of us have taken to running the same kits in our home offices.
So I ordered a Ubiquiti UniFi Security Gateway (USG) and a pair of Dual Radio PRO Wireless Access Points, and I couldn't be more pleased with the end result! Screaming fast wireless access, beautiful command line and web interfaces, and a fantastic product.
There's something quite unique about the UniFi Controller -- the server that "controls" your router, gateway, and access points. Rather than being built into the USG itself, you run the server somewhere else.
Sure you can buy their hardware appliance (which I'm sure is nice). But you can just as easily run it on an Ubuntu machine yourself. That machine could be a physical machine on your network, a virtual machine locally or in the cloud, or it could be an LXD machine container.
I opted for the latter. I'm happily running the UniFi Controller in a LXD machine container, and it's easy for you to setup, too.
I'm running Ubuntu 16.04 LTS 64-bit on an Intel NUC somewhere in my house. It happens to be running Ubuntu Desktop, as it's attached to one of the TVs in my house, as a media playing device. In it's spare time, it's a server I use for LXD, Docker, and other development purposes.
I've configured the network on the machine to "bridge" LXD to my USG router, which happens to be running DHCP and DNS. I'm going to move that to a MAAS server, but that's a post for another day.
Here's /etc/network/interfaces on that machine:
kirkland@masterbr:~⟫ cat /etc/network/interfaces # interfaces(5) file used by ifup(8) and ifdown(8) auto lo iface lo inet loopback auto eth0 iface eth0 inet manual auto br0 iface br0 inet dhcp bridge_ports eth0 bridge_stp off bridge_fd 0 bridge_maxwait 0
So eth0 is bridged, to br0. ifconfig looks like this:
kirkland@masterbr:~⟫ ifconfig eth0 eth0 Link encap:Ethernet HWaddr ec:a8:6b:fb:a1:f2 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:1111309 errors:0 dropped:8294 overruns:0 frame:0 TX packets:539270 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:850773437 (850.7 MB) TX bytes:85706158 (85.7 MB) Interrupt:20 Memory:f7c00000-f7c20000 kirkland@masterbr:~⟫ ifconfig br0 br0 Link encap:Ethernet HWaddr ec:a8:6b:fb:a1:f2 inet addr:10.0.0.8 Bcast:10.0.0.255 Mask:255.255.255.0 inet6 addr: fe80::eea8:6bff:fefb:a1f2/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:435576 errors:0 dropped:0 overruns:0 frame:0 TX packets:182097 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:325950072 (325.9 MB) TX bytes:35439980 (35.4 MB)And I've configured LXD to have its default profile instances draw their IP address from br0, rather than from the default, internally NAT'd dnsmasq lxdbr0.
kirkland@masterbr:/etc⟫ lxc profile show default name: default config: {} description: Default LXD profile devices: eth0: name: eth0 nictype: bridged parent: br0 type: nic
Now, let's launch a LXD container running Ubuntu 16.04 LTS.
kirkland@masterbr:~⟫ lxc launch ubuntu:xenial unifi-controller Creating unifi-controller Starting unifi-controller kirkland@masterbr:~⟫ lxc list +------------------+---------+-------------------+------+------------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +------------------+---------+-------------------+------+------------+-----------+ | unifi-controller | RUNNING | 10.0.0.183 (eth0) | | PERSISTENT | 0 | +------------------+---------+-------------------+------+------------+-----------+
It's important to notice that this container drew an IP address on my 10.0.0.0/24 LAN. It will need this, to detect, federate, and manage the Ubiquiti hardware.
Now, let's exec into it, and import our SSH keys, so that we can SSH into it later.
kirkland@masterbr:~⟫ lxc exec unifi-controller bash root@unifi-controller:~# ssh-import-id kirkland 2016-12-09 21:56:36,558 INFO Authorized key ['4096', 'd3:dd:e4:72:25:18:f3:ea:93:10:1a:5b:9f:bc:ef:5e', 'kirkland@x220', '(RSA)'] 2016-12-09 21:56:36,568 INFO Authorized key ['2048', '69:57:f9:b6:11:73:48:ae:11:10:b5:18:26:7c:15:9d', 'kirkland@mac', '(RSA)'] 2016-12-09 21:56:36,569 INFO [2] SSH keys [Authorized] root@unifi-controller:~# exit exit kirkland@masterbr:~⟫ ssh root@10.0.0.183 The authenticity of host '10.0.0.183 (10.0.0.183)' can't be established. ECDSA key fingerprint is SHA256:we0zAxifd0dcnAE2tVE53NFbQCop61f+MmHGsyGj0Xg. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '10.0.0.183' (ECDSA) to the list of known hosts. root@unifi-controller:~#
Now, let's add the Unifi repository and install the deb and all its dependencies. It's a big pile of Java and MongoDB, which I'm happy to keep nicely "contained" in this LXD instance!
root@unifi-controller:~# echo deb http://www.ubnt.com/downloads/unifi/debian stable ubiquiti deb http://www.ubnt.com/downloads/unifi/debian stable ubiquiti root@unifi-controller:~# echo "deb http://www.ubnt.com/downloads/unifi/debian stable ubiquiti" | sudo tee -a /etc/apt/sources.list deb http://www.ubnt.com/downloads/unifi/debian stable ubiquiti root@unifi-controller:~# apt-key adv --keyserver keyserver.ubuntu.com --recv C0A52C50 Executing: gpg --ignore-time-conflict --no-options --no-default-keyring --homedir /tmp/tmp.hhgdd0ssJQ --no-auto-check-trustdb --trust-model always --keyring /etc/apt/trusted.gpg --primary-keyring /etc/apt/trusted.gpg --keyserver keyserver.ubuntu.com --recv C0A52C50 gpg: requesting key C0A52C50 from hkp server keyserver.ubuntu.com gpg: key C0A52C50: public key "UniFi Developers" imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1) root@unifi-controller:~# apt update >/dev/null 2>&1 root@unifi-controller:~# apt install unifi Reading package lists... Done Building dependency tree Reading state information... Done The following package was automatically installed and is no longer required: os-prober Use 'apt-get autoremove' to remove it. The following extra packages will be installed: binutils ca-certificates-java default-jre-headless fontconfig-config fonts-dejavu-core java-common jsvc libasyncns0 libavahi-client3 libavahi-common-data libavahi-common3 libboost-filesystem1.54.0 libboost-program-options1.54.0 libboost-system1.54.0 libboost-thread1.54.0 libcommons-daemon-java libcups2 libflac8 libfontconfig1 libgoogle-perftools4 libjpeg-turbo8 libjpeg8 liblcms2-2 libnspr4 libnss3 libnss3-nssdb libogg0 libpcrecpp0 libpcsclite1 libpulse0 libsctp1 libsnappy1 libsndfile1 libtcmalloc-minimal4 libunwind8 libv8-3.14.5 libvorbis0a libvorbisenc2 lksctp-tools mongodb-clients mongodb-server openjdk-7-jre-headless tzdata tzdata-java Suggested packages: binutils-doc default-jre equivs java-virtual-machine cups-common liblcms2-utils pcscd pulseaudio icedtea-7-jre-jamvm libnss-mdns sun-java6-fonts fonts-dejavu-extra fonts-ipafont-gothic fonts-ipafont-mincho ttf-wqy-microhei ttf-wqy-zenhei ttf-indic-fonts-core ttf-telugu-fonts ttf-oriya-fonts ttf-kannada-fonts ttf-bengali-fonts The following NEW packages will be installed: binutils ca-certificates-java default-jre-headless fontconfig-config fonts-dejavu-core java-common jsvc libasyncns0 libavahi-client3 libavahi-common-data libavahi-common3 libboost-filesystem1.54.0 libboost-program-options1.54.0 libboost-system1.54.0 libboost-thread1.54.0 libcommons-daemon-java libcups2 libflac8 libfontconfig1 libgoogle-perftools4 libjpeg-turbo8 libjpeg8 liblcms2-2 libnspr4 libnss3 libnss3-nssdb libogg0 libpcrecpp0 libpcsclite1 libpulse0 libsctp1 libsnappy1 libsndfile1 libtcmalloc-minimal4 libunwind8 libv8-3.14.5 libvorbis0a libvorbisenc2 lksctp-tools mongodb-clients mongodb-server openjdk-7-jre-headless tzdata-java unifi The following packages will be upgraded: tzdata 1 upgraded, 44 newly installed, 0 to remove and 10 not upgraded. Need to get 133 MB of archives. After this operation, 287 MB of additional disk space will be used. Do you want to continue? [Y/n] y ... done.
Finally, we point a web browser at this server, http://10.0.0.183:8443/ in my case, and run through the UniFi setup there.
Enjoy!
:-Dustin