Raspberry Pi (2011) model B as Unifi Controller

I have setup new networking equipment to provide a large upgrade to my home network. One component that was required was a small server to manage the access point, a Unifi AP AC Pro.

One option is to purchase a small device from Ubiquiti called a Cloud Key that has the management software pre-loaded. Another option is to install the management software on a Mac, PC, or Linux machine. However, that requires your personal computer to be on anytime you could want to use the software and is a lot of overhead.

I opted to go with a third option – using an old (generation 1) Raspberry Pi model B from 2011 and run the management software from that. I had one just sitting in my desk drawer unused, so it was a perfect opportunity!

To build my UnifiPi Controller (as I am calling it), I took information from two guides and merged them together as described below. This made for a very responsive dedicated device that works quite well!

  1. Begin by downloading and installing the latest Raspbian image from the Raspberry Pi website. This is outside of the scope of this article, but it is fairly trivial to do.
  2. Setup the Raspberry Pi using the raspi-config script. I highly recommend setting the proper keyboard layout for your region first, reboot, then change your passwords and configure the rest of the device defaults. I did the keyboard last and had issues logging in over ssh since the special characters on the default UK keyboard are in a different order than on a US keyboard layout!
    1. TIP: set the memory split to 16MB for the GPU. We’re using this in a headless environment, so wasting memory on the GPU is just going to hurt you.
  3. Fully update the Pi
    sudo aptitude update; sudo aptitude upgrade
  4. reboot
  5. Next fully update the firmware for your Pi
    sudo aptitude install rpi-update; sudo rpi-update
  6. reboot
  7. Set ssh to run on boot
    systemctl enable ssh
    systemctl start ssh
  8. Install and configure the Unifi software
    1. Add the repository
      echo 'deb http://www.ubnt.com/downloads/unifi/debian unifi5 ubiquiti' | sudo tee -a /etc/apt/sources.list.d/ubnt.list > /dev/null
      sudo apt-key adv --keyserver keyserver.ubuntu.com --recv C0A52C50
      sudo aptitude update
    2. Install the software
      sudo aptitude install unifi
    3. Disable the default MongoDB or you’ll have two databases running wasting resources!
      echo 'ENABLE_MONGODB=no' | sudo tee -a /etc/mongodb.conf > /dev/null
    4. Update the Snappy Java Library as Unifi’s version is quite old
      cd /usr/lib/unifi/lib
      sudo mv snappy-java-1.0.5.jar snappy-java-1.0.5.jar.old
      sudo wget http://central.maven.org/maven2/org/xerial/snappy/snappy-java/
      sudo ln -s snappy-java- snappy-java-1.0.5.jar
    5. Remove the Unifi Cloud Library (ONLY NEEDED FOR ARMv6 devices – basically anything prior to the 3rd generation Pi)
      sudo rm /usr/lib/unifi/lib/native/Linux/armhf/libubnt_webrtc_jni.so
    6. Switch to the official Java client instead of OpenJDK. OpenJDK is horrible and resource intensive
      sudo aptitude install oracle-java8-jdk
      sudo update-alternatives --config java
      #Select Java8 - was item 2 for me
      java -showversion (to confirm it's set properly)
  9. reboot

You can now access the Raspberry Pi via the IP address pulled from DNS:
ssh pi@

Using the web interface running on port 8443 you can also configure any new Unifi APs.  You can also connect the Unifi iPhone app to manage your AP from your mobile device.  However, as I do not have a Unifi Secure Gateway, I am unable to get WAN/LAN stats.  But, I can get those separately through the EdgeRouter web UI.


  • I decided to not setup a static IP address as I will use functions in my EdgeRouter Lite to set a static IP via MAC address.
  • I currently only have one Unifi AP but can expand to more as needed. However, given the size of my house and the location I was able to place the AP, that is unlikely to be needed.


 Linux Authentication Testing 

I am coming out of a very long hiatus of posting to my site to start posting content I feel is interesting. You, however, may be put to sleep by it!

Today we are going to take a look at how to test various Linux authentication methods. As an example, let’s assume we have an MTA and which validates users against a LDAP database. We are unable to authenticate to the MTA but we also are unsure where the process is breaking down.

Typically, in this setup, the MTA talks to Cyrus SASL. SASL then communicates to PAM. The relevant PAM module then talks to LDAP.  Here we have four layers to test. Let’s test each starting from the bottom.


As all of our users are stored in a LDAP database with proper credentials, we should have no issues authenticating. If errors here are encountered, then there are problems with our ldap.conf file, firewall issues, or possibly even a configuration error on the LDAP server itself. However, it’s always best to start by looking for issues with the local client.

To test LDAP, we need to know what our base DN is, what the LDAP uri is, and some authentication credentials to test with. The following command will perform the required test.

ldapwhoami -vvv -h some.ldap.host.com -p 389 -D uid=keith,ou=ldapou,dc=somewhere,dc=com -x -Z -W
ldap_initialize( ldap://some.ldap.host.com:389 )
Enter LDAP Password:
Result: Success (0)

As we can see, we were returned a success, so this layer is fine. A note that the -Z flag tells the ldap utility to use a TLS connection to the remote server. This is required in most cases for authentication requests or just for improved LDAP service security.


The next step is to test PAM. PAM stands for Pluggable Authentication Modules and lets a system administrator decide how a specific system service will authenticate users. This idea lets the service or application not worry about the details of authentication but rather just know whether an authentication attempt was successful or not. Because of the modular nature, this also lets the administrator swap out one authentication method for another at almost anytime.

In this case, however, we will be using PAM against an LDAP database.  As I do not know low-level programming, and I was unable to find a way to test a specific PAM module directly, I took to Google and found pamtester.  One note is that I had to install pam-devel and gcc-c++ for the binary to build properly.  Once built, the small utility will allow testing of a specific PAM module very easily from the command line.

pamtester smtp keith authenticate
pamtester: successfully authenticated

As we can see, we can authenticate using the PAM smtp module (typically /etc/pam.d/smtp).  This ensures that PAM is able to communicate over ldap to our authentication source.  If any errors are displayed, you will need to debug from there.  Perhaps you do not have enough packages installed, or something is configured incorrectly.

Cyrus SASL

Next up is to test SASL.  SASL stands for Simple Authentication and Security Layer and lets authentication act in a more modular method.  Here, a configuration file for our MTA tells SASL which authentication methods to support.  In this case we will support both plain and login.  plain is a password authentication method.  While this can be insecure, our MTA will only allow the transmission of login data to be sent over a TLS encrypted channel.  login basically just checks against system logins available and is a backup but never used if plain is setup properly.

To test the SASL configuration, use the built-in testsaslauthd command.  It should be included with your sasl package.

testsaslauthd -u keith -s smtp -p CleartextPassword
0: OK "Success."

Great – our test succeeded!  If any errors are shown instead, you may have issues either with your sasl configuration in general, or possibly even with PAM again.  The -s smtp tells SASL to essentially use the smtp PAM module.  One thing you can do to debug is to enable debug mode in saslauthd.  I did this by editing /etc/sysconfig/saslauthd and adding the -d flag after -l.  Restart the service then it should dump debug output to the screen.  Revert the change after you’d fixed issues found.

Also, because you must type your password on the command line, be sure to go back in your history, backspace through the password, then press the down arrow.  That will modify your bash history to remove the password from visibility.


Finally, let’s test your MTA.  This will make sure that everything is tied together fully – from MTA, to SASL, to PAM, then finally to LDAP.  Since we’re going to be sending login credentials, we’ll test over port 587 using TLS.

openssl s_client -connect mta.hostname.somewhere.com:587 -starttls smtp
ehlo localhost
AUTH PLAIN [base64 encoded user/pass goes here]
235 2.0.0 OK Authenticated

The above test succeeded.  This means we are able to authenticate successfully through all four layers.  If encountering errors above, ensure that your SASL path is configured correctly.  This means that if you’re running a 64bit distribution, you have your MTA built against /usr/lib64/sasl2/ and you have the appropriate configuration in that directory as well.  For sendmail, that would be a properly setup Sendmail.conf file.


I hope to post these types of things more regularly as they help me to document items I have worked on, as well as provide assistance for others who may have similar issues in the future.  Additionally, this type of post, while not for everyone, is interesting to me and is fun to write!