Change UniFi Camera Password from Command Line

Basic steps are

  • Change password with passwd
  • Copy passwd hash to /tmp/system.cfg
  • Apply Changes

Changing Password with passwd

The passwd command is normally used for changing the password for a Linux user. We’ll use it to change our user password and then copy the hash out of the /etc/passwd file to use in the Ubiquiti config file.

UVC.v4.18.37.67# passwd
Changing password for admin
New password:
Retype password:
passwd: password for admin changed by admin

Copy passwd hash to /tmp/system.cfg

Using “cat /etc/passwd”, we can get what the new password hash is and can copy that into the /tmp/system.cfg file.

UVC.v4.18.37.67# cat /etc/passwd

Open up the /tmp/system.cfg config file, find the section below and replace the hash part, i.e. the part that is in bold.

As a side note, you can copy and past all of the “users.1.*” lines and change the 1 to 2 and have a second user.

Apply Changes

You can use the following command to write the changes and then reboot the camera.

cfgmtd -f /tmp/system.cfg -w && reboot

Long Example

[admin@localhost ~]$ ssh ubnt@
ubnt@'s password:
BusyBox v1.29.2 () built-in shell (ash)
UVC.v4.18.37.67# passwd
Changing password for admin
New password:
Retype password:
passwd: password for admin changed by admin
UVC.v4.18.37.67# cat /etc/passwd
UVC.v4.18.37.67# vi /tmp/system.cfg <- Edit the text file and replace the hash with the one from above
UVC.v4.18.37.67# cfgmtd -f /tmp/system.cfg -w && reboot

Upgrade AirFiber 11 to 4.1 from SSH

Quick list of commands

ssh ubnt@  <- Replace with username and IP address
cd /tmp
mv AF11.v4.1.0.bin fwupdate.bin
/sbin/fwupdate -m
  1. Upload the firmware using FTP or SCP to the /tmp directory
  2. Rename the file from AF11…bin to fwupdate.bin
  3. Start the upgrade with
/sbin/fwupdate -m

Wait for it to finish upgrading

Reset UniFi to Factory Defaults – Command Line

SSH into the UniFi. Note that the UniFi username and password get updated from the controller. Refer to here to find username and password.

ssh ubnt@

run the script with the restore-default option restore-default

Once the device is reset, log in over ssh and reconfigure.

Note that the username and password will now be ubnt/ubnt

Install UniFi 5.6.42 in Docker

Pull UniFi 5.6.42 docker image

sudo docker pull jacobalberty/unifi:5.6.42

Install image

sudo docker run -d --init --restart=unless-stopped --name=unifi-controller --net=host --volume=/docker/unifi:/var/lib/unifi -p 8080:8080/tcp -p 8081:8081/tcp -p 8443:8443/tcp -p 8843:8843/tcp -p 8880:8880/tcp -p 8883:8883/tcp -p 3478:3478/udp jacobalberty/unifi:5.6.42

Access and setup the unifi controller from a browser.


UNMS is starting… Repairing UNMS

UNMS is starting

Checking log files.

Log files are located in /home/unms/data/logs

larry@localhost:~$ sudo tail -f /home/unms/data/logs/unms.b5a3713b02f71e06fb3a84a3a9a75c558.log
{"msg":"setting permissions on /home/app/unms/data/control","name":"unknown","hostname":"unknown","pid":0,"v":0,"level":30,"tag":"unms","time":"2020-04-17T16:28:35+00:00"}
{"msg":"Linking /home/app/unms/public/site-images -> /home/app/unms/data/images","name":"unknown","hostname":"unknown","pid":0,"v":0,"level":30,"tag":"unms","time":"2020-04-17T16:28:35+00:00"}
{"msg":"Linking /home/app/unms/public/firmwares -> /home/app/unms/data/firmwares","name":"unknown","hostname":"unknown","pid":0,"v":0,"level":30,"tag":"unms","time":"2020-04-17T16:28:35+00:00"}
{"msg":"Stepping down from root: su-exec \"/usr/local/bin/\" \"index.js\"","name":"unknown","hostname":"unknown","pid":0,"v":0,"level":30,"tag":"unms","time":"2020-04-17T16:28:35+00:00"}
{"msg":"Running docker-entrypoint index.js","name":"unknown","hostname":"unknown","pid":0,"v":0,"level":30,"tag":"unms","time":"2020-04-17T16:28:35+00:00"}
{"msg":"Version: 1.1.6+e6ec4747d.2020-03-13T10:52:14+01:00","name":"unknown","hostname":"unknown","pid":0,"v":0,"level":30,"tag":"unms","time":"2020-04-17T16:28:35+00:00"}
{"msg":"Waiting for database containers","name":"unknown","hostname":"unknown","pid":0,"v":0,"level":30,"tag":"unms","time":"2020-04-17T16:28:35+00:00"}
{"msg":"psql: fe_sendauth: no password supplied","name":"unknown","hostname":"unknown","pid":0,"v":0,"level":30,"tag":"unms","time":"2020-04-17T16:28:35+00:00"}
{"msg":"nc: bad address 'unms-redis'","name":"unknown","hostname":"unknown","pid":0,"v":0,"level":30,"tag":"unms","time":"2020-04-17T16:28:35+00:00"}


sudo ~unms/app/unms-cli stop

Start UNMS

sudo ~unms/app/unms-cli start

Fix Redis AOF

sudo ~unms/app/unms-cli fix-redis-aof

Running the above command resolved the problem and let UNMS start working.

larry@localhost:~$ sudo ~unms/app/unms-cli stop
larry@localhost:~$ sudo ~unms/app/unms-cli fix-redis-aof
Creating network "unms_internal" with the default driver
Creating network "unms_public" with the default driver
Creating unms-fluentd
The AOF appears to start with an RDB preamble.
Checking the RDB preamble to start:
[offset 0] Checking RDB file --fix
[offset 26] AUX FIELD redis-ver = '5.0.5'
[offset 40] AUX FIELD redis-bits = '64'
[offset 52] AUX FIELD ctime = '1587130996'
[offset 67] AUX FIELD used-mem = '276217328'
[offset 83] AUX FIELD aof-preamble = '1'
[offset 85] Selecting DB ID 0
[offset 80304063] Checksum OK
[offset 80304063] \o/ RDB looks OK! \o/
[info] 3307 keys read
[info] 0 expires
[info] 0 already expired
RDB preamble is OK, proceeding with AOF tail…
0x 79b7264: Expected prefix '*', got: '
AOF analyzed: size=127631360, ok_up_to=127627876, diff=3484
This will shrink the AOF from 127631360 bytes, with 3484 bytes, to 127627876 bytes
Continue? [y/N]: Successfully truncated AOF
larry@localhost:~$ sudo ~unms/app/unms-cli start

On the forums they seemed to recommend stopping the service and running

sudo ~unms/app/unms-cli rewrite-redis-aof

I was getting the following error when trying to run this command. Running the above command worked though.

larry@localhost:~$ sudo ~unms/app/unms-cli stop
larry@localhost:~$ sudo redis-check-aof --fix ~unms/data/redis/appendonly.aof
The AOF appears to start with an RDB preamble.
Checking the RDB preamble to start:
[offset 0] Checking RDB file --fix
[offset 9] Can't handle RDB format version 9
[additional info] While doing: start
[additional info] Reading type 0 (string)
[info] 0 keys read
[info] 0 expires
[info] 0 already expired
RDB preamble of AOF file is not sane, aborting.

MongoDB – dpkg-deb: error: paste subprocess was killed by signal (Broken pipe)

Ran into an issue when trying to figure out some problems with UniFi and UniFi-Video. Upgrading both to the latest version was causing problems, because they both needed different versions of MongoDB.

Was getting the following error when trying to install MongoDB. Think I was trying to install Mongo following the instructions on their site and then it caused issues with apt.

dpkg: error processing archive /var/cache/apt/archives/mongodb-org-server_4.2.5_amd64.deb (--unpack):
trying to overwrite '/usr/bin/mongod', which is also in package mongodb-server-core 1:3.6.3-0ubuntu1.1
dpkg-deb: error: paste subprocess was killed by signal (Broken pipe)

Removed the following file

rm /etc/apt/sources.list.d/mongodb-org-4.2.list

and was able to use apt again to install MongoDB. Didn’t end up solving my problem because I technically needed two versions, but at least apt was being nice again. Ended up installing the UniFi controller docker container and can run both on the same server that way.

Auto renew SSL Cert with UniFi running in Docker

Setting up the SSL cert for UniFi service when running in docker is fairly easy to do. All you have to do is modify the UniFi SSL renew script to use the UniFi Docker directory and change the start and stop service to start and stop the Docker container. The script below should be ready to go.

Download, chmod +x it, and run, drop it in cron to auto renew.

In the below script, change (unifiDir=”/docker/unifi”) to your UniFi directory.

Note: this triggers calling the script that will send an update to Microsoft Teams to let you know that the certs should be renewed. Check here for more info.

#!/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: 04/10/2020
# 04/10/2020: Changed directories and commands to work with a UniFi Docker install
# 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 <fryfrog[at]> 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
# LEBINARY="/usr/src/letsencrypt/certbot-auto"

# Change to your UniFi Docker directory


function usage() {
  echo "Usage: $0 -d <domain> [-e <email>] [-r] [-i]"
  echo "  -d <domain>: The domain name to use."
  echo "  -e <email>: 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

  docker container stop ${dockerContainerId}
  sleep 10
  dockerContainerId=$(sudo docker container list | grep unifi-controller | awk '{print $1}')
  echo "Removing existing certificate from Unifi protected keystore..."
  keytool -delete -alias unifi -keystore ${unifiDir}/keystore -deststorepass aircontrolenterprise

  echo "Inserting certificate into Unifi keystore..."
  keytool -trustcacerts -importkeystore \
          -deststorepass aircontrolenterprise \
          -destkeypass aircontrolenterprise \
          -destkeystore ${unifiDir}/keystore \
          -srckeystore "${TEMPFILE}" -srcstoretype PKCS12 \
          -srcstorepass aircontrolenterprise \
          -alias unifi

  sleep 2
  echo "Starting Unifi controllers..."
  docker container start ${dockerContainerId}
  ./ -b "$(hostname) - UniFi service is restarting, ssl cert should be renewed."

  echo "Done!"

Installing UniFi controller in Docker Container

Instructions followed from here. Some changes were made
Commands work on Ubuntu 16.04

Install Docker

sudo apt install -y docker
systemctl enable docker
systemctl start docker

Install UniFi

sudo docker pull jacobalberty/unifi:latest

Setup Docker Image

The following command sets up a container which we can later manipulate to start and stop the “service”
You can specify where you want the UniFi files to reside if desired.

sudo docker run -d --init --restart=unless-stopped --name=unifi-controller --net=host --volume=/docker/unifi:/var/lib/unifi -p 8080:8080/tcp -p 8081:8081/tcp -p 8443:8443/tcp -p 8843:8843/tcp -p 8880:8880/tcp -p 8883:8883/tcp -p 3478:3478/udp jacobalberty/unifi:latest

Docker commands

List docker containers

sudo docker container list
367c7a1465ec        jacobalberty/unifi:latest   "/usr/loca/bin/dock…" 15 minutes ago      Up 14 minutes (healthy) unifi-controller

List docker images on system

sudo docker images
jacobalberty/unifi latest baebbe301633 9 days ago 711MB

Stop container. Also stops the UniFi service. Change the ID to your container ID.

sudo docker stop 367c7a1465ec

Other notes

When setting up the Docker image, the directory specified was “/docker/unifi” so all the UniFi files are in there and it looks like if you manipulate the files, it makes the changes fine. At least for setting up the SSL certificates.

unifi depends on mongodb-server (<< 1:3.6.0) | mongodb-10gen (<< 3.6.0) ...

Looks like the issue is that the UniFi server can’t be installed with a version of MongoDB newer then 3.6.0

Fix the issue by installing an older version of MongoDB

wget -qO - | sudo apt-key add -
echo "deb xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list
sudo apt-get update

Then install MongoDB with

apt install mongodb-org-server

You may run into issues if you already have a version of Mongo installed. Uninstall it and then rerun the above install command.