Configure AirOS SNMP settings over ssh

ubntmod command with save without rebooting.

./ -i -s "private;;[30.69636, -88.04811]" -X '/usr/etc/rc.d/rc.softrestart save'


ssh ubnt@

Open config file

vi /tmp/system.cfg

Find the SNMP settings and modify as needed. Example below
snmp.location=[30.69636, -88.04811]

Save and exit file with :x

Apply settings

/usr/etc/rc.d/rc.softrestart save

Auto renew ssl cert for UniFI and UniFi-Video

The following script was taken from here
Added unifi-video support. Script uses letsencrypt to get the cert and automatically updates the UniFi and UniFi-Video Keystores.

Would be a good idea to check and make sure the the UniFi-Video cameras reconnect and still work.

You should be able to add the script to a cronjob to auto renew the certificate.

Run the script wit no or the -h argument to show the options and arguments to use.

./ -h

Copy and paste script into file, chmod +x

#!/usr/bin/env bash
# Added support to do UniFi and UniFi controllers at the same time using the same cert.
# Original script from
# More info here 
# And here
# Modified script from here:
# Modified by: Brielle Bruns 
# Download URL:
# Version: 1.7
# Last Changed: 09/26/2018
# 02/02/2016: Fixed some errors with key export/import, removed lame docker requirements
# 02/27/2016: More verbose progress report
# 03/08/2016: Add renew option, reformat code, command line options
# 03/24/2016: More sanity checking, embedding cert
# 10/23/2017: Apparently don't need the ace.jar parts, so disable them
# 02/04/2018: LE disabled tls-sni-01, so switch to just tls-sni, as certbot 0.22 and later automatically fall back to http/80 for auth
# 05/29/2018: Integrate patch from Donald Webster  to cleanup and improve tests
# 09/26/2018: Change from TLS to HTTP authenticator

# Location of LetsEncrypt binary we use.  Leave unset if you want to let it find automatically


function usage() {
  echo "Usage: $0 -d  [-e ] [-r] [-i]"
  echo "  -d : The domain name to use."
  echo "  -e : Email address to use for certificate."
  echo "  -r: Renew domain."
  echo "  -i: Insert only, use to force insertion of certificate."

while getopts "hird:e:" opt; do
  case $opt in
    i) onlyinsert="yes";;
    r) renew="yes";;
    d) domains+=("$OPTARG");;
    e) email="$OPTARG";;
    h) usage

DEFAULTLEBINARY="/usr/bin/certbot /usr/bin/letsencrypt /usr/sbin/certbot
  /usr/sbin/letsencrypt /usr/local/bin/certbot /usr/local/sbin/certbot
  /usr/local/bin/letsencrypt /usr/local/sbin/letsencrypt
  /usr/src/letsencrypt/certbot-auto /usr/src/letsencrypt/letsencrypt-auto
  /usr/src/certbot/certbot-auto /usr/src/certbot/letsencrypt-auto
  /usr/src/certbot-master/certbot-auto /usr/src/certbot-master/letsencrypt-auto"

if [[ ! -v LEBINARY ]]; then
  for i in ${DEFAULTLEBINARY}; do
    if [[ -x ${i} ]]; then
      echo "Found LetsEncrypt/Certbot binary at ${LEBINARY}"

# Command line options depending on New or Renew.
NEWCERT="--renew-by-default certonly"
RENEWCERT="-n renew"

# Check for required binaries
if [[ ! -x ${LEBINARY} ]]; then
  echo "Error: LetsEncrypt binary not found in ${LEBINARY} !"
  echo "You'll need to do one of the following:"
  echo "1) Change LEBINARY variable in this script"
  echo "2) Install LE manually or via your package manager and do #1"
  echo "3) Use the included script to install it"
  exit 1

if [[ ! -x $( which keytool ) ]]; then
  echo "Error: Java keytool binary not found."
  exit 1

if [[ ! -x $( which openssl ) ]]; then
  echo "Error: OpenSSL binary not found."
  exit 1

if [[ ! -z ${email} ]]; then
  email="--email ${email}"

shift $((OPTIND -1))
for val in "${domains[@]}"; do
        DOMAINS="${DOMAINS} -d ${val} "


if [[ -z ${MAINDOMAIN} ]]; then
  echo "Error: At least one -d argument is required"
  exit 1

if [[ ${renew} == "yes" ]]; then

if [[ ${onlyinsert} != "yes" ]]; then
  echo "Firing up standalone authenticator on TCP port 80 and requesting cert..."
  ${LEBINARY} --server \
              --agree-tos --standalone --preferred-challenges http ${LEOPTIONS}

if [[ ${onlyinsert} != "yes" ]] && md5sum -c "/etc/letsencrypt/live/${MAINDOMAIN}/cert.pem.md5" &>/dev/null; then
  echo "Cert has not changed, not updating controller."
  exit 0
  echo "Cert has changed or -i option was used, updating controller..."

  # Identrust cross-signed CA cert needed by the java keystore for import.
  # Can get original here:
  cat > "${CATEMPFILE}" <<'_EOF'

  md5sum "/etc/letsencrypt/live/${MAINDOMAIN}/cert.pem" > "/etc/letsencrypt/live/${MAINDOMAIN}/cert.pem.md5"
  echo "Using openssl to prepare certificate..."
  cat "/etc/letsencrypt/live/${MAINDOMAIN}/chain.pem" >> "${CATEMPFILE}"
  openssl pkcs12 -export  -passout pass:aircontrolenterprise \
          -in "/etc/letsencrypt/live/${MAINDOMAIN}/cert.pem" \
          -inkey "/etc/letsencrypt/live/${MAINDOMAIN}/privkey.pem" \
          -out "${TEMPFILE}" -name unifi \
          -CAfile "${CATEMPFILE}" -caname root

  echo "Stopping Unifi and UniFi-Video controllers..."
  systemctl stop unifi unifi-video  

  echo "Removing existing certificate from Unifi protected keystore..."
  keytool -delete -alias unifi -keystore /usr/lib/unifi/data/keystore -deststorepass aircontrolenterprise
  echo "Removing existing certificate from Unifi-Video protected keystore..."
  keytool -delete -alias unifi -keystore /usr/lib/unifi-video/data/keystore -deststorepass ubiquiti
  # following lines are needed for unifi-video
  echo "Inserting certificate into Unifi keystore..."
  keytool -trustcacerts -importkeystore \
          -deststorepass aircontrolenterprise \
          -destkeypass aircontrolenterprise \
          -destkeystore /usr/lib/unifi/data/keystore \
          -srckeystore "${TEMPFILE}" -srcstoretype PKCS12 \
          -srcstorepass aircontrolenterprise \
          -alias unifi

  echo "Inserting certificate into Unifi-Video keystore..."
  keytool -trustcacerts -importkeystore \
          -deststorepass ubiquiti \
          -destkeypass ubiquiti \
          -destkeystore /usr/lib/unifi-video/data/keystore \
          -srckeystore "${TEMPFILE}" -srcstoretype PKCS12 \
          -srcstorepass aircontrolenterprise \

          rm -f "${TEMPFILE}" "${CATEMPFILE}"

  mv /usr/lib/unifi-video/data/ufv-truststore{,.old} # Delete old unifi-video keystore
  sleep 5
  echo "Starting Unifi and UniFi-Video controllers..."
  systemctl start unifi unifi-video 

  echo "Done!"

Errors Renewing Lets Encrypt Certificate for UniFi-Video

Had an issue with the Lets Encrypt cert for a UniFi-Video server.  When renewing the cert and reimporting it into the UniFi-Video keystore, the certification was showing out of date.

Issue ended up being something with certbot.

When certbot runs it generates a new cert.pem, chain.pem, fullchain.pem and privkey.pem and puts them in the “/etc/letsencrypt/live/” directory.

The privkey.pem and cert.pem are used to create the keys.p12 file which gets imported into the UniFi-Video keystore.

Apparently the .pem files in “/etc/letsencrypt/live/” are symbolic links to files in “/etc/letsencrypt/archive/”

Upon inspection of the archive directory, multiple cert.pem and privkey.pem files were found with the names cert1.pem, cert2.pem, cert3.pem etc.  Looking at the creation date of the file revealed the symbolic link was referring to an old “cert1.pem” file.

Work around was to stop the unifi-video service and reimport the cert using the latest .pem files in the archive directory.

echo ubiquiti | openssl pkcs12 -export -inkey /etc/letsencrypt/archive/ -in /etc/letsencrypt/archive/ -name airvision -out /usr/lib/unifi-video/data/keys.p12 -password stdin
echo y | keytool -importkeystore -srckeystore /etc/letsencrypt/archive/ -srcstoretype pkcs12 -destkeystore /usr/lib/unifi-video/data/keystore -storepass ubiquiti -srcstorepass ubiquiti

Remove the old ufv-truststore and start the service.

mv /usr/lib/unifi-video/data/ufv-truststore{,.old}
systemctl start unifi-video

Worked like a charm.

Add a SSL Certificate to Ubiquiti UniFi-Video server using Lets Encrypt

Install certbot

sudo apt-get install python-certbot

Generate certificate.  Change to the domain name you have pointing to your UniFi-Video controller.

sudo certbot certonly -d

Certbot will create the files in “/etc/letsencrypt/live/”

Now you should stop the unifi service.

systemctl stop unifi-video

The following two commands create and install the keystore for the UniFi-Video application.  These commands were copied from here.  Thanks scobber!

echo ubiquiti | openssl pkcs12 -export -inkey /etc/letsencrypt/live/ -in /etc/letsencrypt/live/ -name airvision -out /usr/lib/unifi-video/data/keys.p12 -password stdin
echo y | keytool -importkeystore -srckeystore /etc/letsencrypt/live/ -srcstoretype pkcs12 -destkeystore /usr/lib/unifi-video/data/keystore -storepass ubiquiti -srcstorepass ubiquiti

Remove or rename the Trusted Store.  If you don’t, the cameras will connect, but will not record.  The controller will rebuild the ufv-truststore when it starts up and the cameras will be able to record.

mv /usr/lib/unifi-video/data/ufv-truststore{,.old}

Start the UniFi-Video service

systemctl start unifi-video

Now you can check it by going to

Ubuntu UniFi server running out of space on /run

Had an issue that /run was randomly running out of space which in turn would interfere with the unifi-video service causing it to run, but not record.

/run looks like a tmpfs or ramdisk that Ubuntu sets up.  So you can do a “temporary” fix by remounting the tmpfs with a larger size.  Example below.  If /run is a 2GB directory, you can remount changing the size from 2GB to 2.5GB.

sudo mount -t tmpsfs tmpfs /run -o remount,size=2500M

Note that it is a temporary fix and goes away after a reboot.

The issue ended up being that the WiFi UniFi controller was setup to auto backup everything once a week.  So as it was backing stuff up, it would eat up the available space in the tmpfs, think there may be an issue with the size of the UniFi data and maybe not being able to fit it all in RAM?

Running the following command

df -h --max=1 /var | sort

shows the following

1.1M /run/udev
2.5G /run/
2.5G /run/unifi   <-- UniFi controller
4.0K /run/initramfs
8.0K /run/network
12K /run/user
288K /run/samba
404K /run/systemd

Looking inside the unifi directory shows the following folders.  Looks like the they are temp files.

200M /run/unifi/ExpTmp351719567129045774
696M /run/unifi/ExpTmp3406220793759111216
1.6G /run/unifi/ExpTmp3368400690321364109
0 /run/unifi/work
2.5G /run/unifi

Running an ls inside the folder shows

-rw-r----- 1 unifi unifi 13971807 Jul 2 02:30 db.gz
-rw-r----- 1 unifi unifi 1665223462 Jul 2 02:56 db_stat.gz

Looking inside the UniFi controller it is set to auto backup on Monday at 2:30AM

Looks like “/run/unifi” is used as a temporary folder to create the backups and when it is completed converts it to a .unf file and moves it to “/usr/lib/unifi/data/backup/autobackup/”  So the left over temp files were never completed or something caused them to stop working.  Maybe the backup was big enough to take up all the tmpfs space and cause the backup to fail.

Resolution.  To fix the problem I turned the data retention down to a week and deleted the temp files in /var/unifi.  Had to sudo su to root.  sudo wasn’t cutting it for some reason.

sudo su
rm -rf /var/unifi/Exp*

Should be all good now.

Remove AirControl provisioning from Ubiquiti radio via SSH

Short version

List AirControl server(s)


Remove from AirControl Server

mca-provision-rm http://server-address


Expanded Steps

First you’ll need to SSH into your radio


ssh ubnt@

Next run “mca-provision-list” to list the connection(s) the radio has, or is trying to connect to.  If you have had the radio connected to multiple AirControl servers it will show more than one entry.


XM.v6.1.3# mca-provision-list
unknown @ -

To remove, run “mca-provision-rm” with the AirControl address.  You can simple use the “http://server-ip”, shouldn’t have to worry about the port number/AC2/report.


XM.v6.1.3# mca-provision-rm
Found 1 entries matching '':
Removing: unknown @ ...
Found Backup1 on[1] ...
Found Active on[2] ...
Storing Active[1] ... [%100]
Active->Backup[2] ... [%100]


Install Ubiquiti UNMS on Ubuntu

Ubiquiti UNMS installation instructions link

Download and Install UNMS

curl -fsSL > /tmp/ && sudo bash /tmp/

Run the following commands as root.  Use sudo su if needed.

Set over commit to 1

echo "vm.overcommit_memory=1" >>/etc/sysctl.conf
sysctl -p

Disable Transparent HugePages

echo never > /sys/kernel/mm/transparent_hugepage/enabled

Add this to /etc/rc.local above the exit line

if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
   echo never > /sys/kernel/mm/transparent_hugepage/defrag

Finish the installation in your browser

Add extra drive to UniFi Video Controller

Find your disk drive using fdisk or some other utility.  More info here.

fdisk -l


steve@ubuntu:~$ sudo fdisk -l
Disk /dev/sda: 32 GiB, 34359738368 bytes, 67108864 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xe96d30af

Device     Boot    Start      End  Sectors Size Id Type
/dev/sda1  *        2048 58720255 58718208  28G 83 Linux
/dev/sda2       58722302 67106815  8384514   4G  5 Extended
/dev/sda5       58722304 67106815  8384512   4G 82 Linux swap / Solaris

Disk /dev/sdb: 557 GiB, 598074195968 bytes, 1168113664 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

The drive is the 500GiB drive /dev/sdb

Create a partition on the drive.  Warning!  Be careful when formatting drives and make sure you don’t format the wrong one!

echo ';' | sfdisk /dev/sdb

You should now see the partition when you run fdisk -l again.  If you run into issues mounting the drive, try formating the drive with a different utility i.e.(fdisk, cfdisk, gparted etc.)

steve@ubuntu:~$ sudo fdisk -l
Disk /dev/sdb: 557 GiB, 598074195968 bytes, 1168113664 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x717f99ba

Device     Boot Start        End    Sectors  Size Id Type
/dev/sdb1        2048 1168113663 1168111616  557G 83 Linux   <--New Partition

Create mount point

mkdir -p /video/mount/point

Now mount the partition

mount /dev/sdb1 /video/mount/point

Allow unifi-video user to own the mount point

chown -R video/mount/point

Add the drive to /etc/fstab to auto mount on system bootup.  More info here.

Change /dev/sdXx to your drive and /MOUNTLOCATION to your mount location.

sudo echo "/dev/sdXx /MOUNTLOCATION ext4 rw,defaults 0 0 " >> /etc/fstab


sudo echo "/dev/sdb1 /video/mount/point ext4 rw,defaults 0 0 " >> /etc/fstab

If you have issues running the above command, you can manually add it to the file with

sudo vi /etc/fstab

add the following line to the bottom of the file.  Change sdXx to your drive and /MOUNTLOCATION to the mount location of the drive.

/dev/sdXx /MOUNTLOCATION ext4 rw,defaults 0 0

You can reboot the system to make sure that the drive mounts properly.

Now you can log into the UniFi Video controller and set the Recording Path by going to Settings>SYSTEM CONFIGURATION>CONFIGURE and set the Recording Path to /video/mount/point

Tip. In the SYSTEM CONFIGURATION menu you can hover over the Disk and it’ll show you your total amount of recording space.

Install UniFi Video 3.8.5 on Ubuntu or Debian

You can run all the commands from the terminal, or ssh into the server

See here if you need to setup SSH on the server.

Install prerequisites

sudo apt-get install mongodb mongodb-server openjdk-8-jre-headless jsvc

Download UniFi Video installer

Note the Debian package works on Ubuntu, and has been tested on the latest Ubuntu


Install package

sudo dpkg -i unifi-video.Debian7_amd64.v3.8.5.deb

Login to the UniFi Video controller using your web browser and going to the following address to finish configuring the NVR.