Backup UISP Application Backup Files with Rsync

UISP runs inside of a docker container. To copy out the backup files we need to use the “docker cp” command.

sudo docker cp unms:/home/app/unms/data/unms-backups ./uisp-backups

This will copy the backups into ./uisp-backups directory.

On an Ubuntu system, docker needs sudo permissions. If you copy the backups with the above command, the backup files will be assigned to the root user and you will not be able to use your normal user to manipulate the files.

You can either add your current user to the Docker group, or change the files owner

sudo chown username:username -R ./uisp-backups/

We can now copy all the automatic backups with rsync

sudo rsync -a ./uisp-backups -e "ssh -p 22" backupuser@backuphost:/backups

You can also automate this with Cron by doing something like

1 1 * * 1 docker cp unms:/home/app/unms/data/unms-backups ~/uisp-backups && rsync -a ~/uisp-backups -e "ssh -p 22" backupuser@backuphost:/backups

Every Monday at 1:01AM, copy the current UISP automatic backups, then use rsync to copy them to a remote server.

This expects that the current user has permissions to call Docker without sudo.

Voxer Bot Attempts

The following are various notes and findings on trying to create a “Bot” for Voxer. Voxer doesn’t really have any options for web hooks, and the SDK is still in beta. We’ll be exploring sending messages to a channel, how to use Curl or Fetch to send messages. Unfortunately, signing in does not appear to be easy to automate.

Looking at Voxer

Voxer is primarily used via the modile apps, but there is also a web version at web.voxer.com

Using Firefox, we can play with the Web Tools to get a better idea of what is going on.

All the Javascript is easily readable. api.js is of interest. This can helps us understand how messages are sent.

The Web interface seems to be somewhat buggy, could be it just doesn’t like going through burp, but had better luck monitoring the channel for new messages from a phone.

Proxying the traffic through Burp is tricky. The log in does not appear to work while the proxy is active, but you can log in, and then activate the proxy to capture and replay sending messages.

If you get “Voxer is open in another tab. Please click ‘OK’ then close this tab.” clear all voxer cookies and log in again. Seems to happen quite often.

Interestingly, if you send a message, then send that message POST request to Repeater, change the text and resubmit it, it “Updates” the text of the message. So if you know the message_id, or maybe the create_time, you can change the text in messages.

About Sending Messages

When you send a message, there are 2 POST requests sent. The first one sends the message and the second one consumes the message. It looks like you really only need the first post message request to actually send messages. Think the consume message post is for the browser to trigger a refresh on the messages in the message list.

There are two variables that change message to message

message_id and create_time

Looking into the api.js file we see that create_time is done with the following code

now = new Date().getTime() / 1000,

And here is the code used to generate the message_id. First part is the time, the next part is random.

window.generate_message_id = function (type) {
        var message_id = new Date().getTime() + "_" + Math.floor((Math.random() * 10000000000) + 1000);

        if (type && type === "image") {
            message_id += "_v1.jpg";
        }

        return message_id;
    };

Structure of the POST request

The following entries are slightly abbreviated

Cookies

There are a bunch of tracking cookies, the session cookie is the one we are interested in. The Rv_session_key is what will allow us to actually send messages. As a side note, it appears that every time we send a message, there is analytics that is also sent, saying who the message was sent to, and when.

session={"gcp1-prod":{"user_id":"MyVoxerUser_ID","Rv_session_key":"db0bc8a069148140151a38bab2098a01"}}

Body

{"message_id":"1681191108600_7318671093","create_time":1681191108,"model":"User_Agent","content_type":"text","from":"MyVoxerUser_ID","subject":"Walkie","body":"This is the text of the message","thread_id":"This.is.the.thread_id"}

Using JavaScript / fetch

After some trial an error, the following solution finally worked. You can copy the following code, and run with “node file.js”

// Change variables as needed
let body = "Hello World!"
// let body = process.argv.slice(2) // You can use this if you want to pass in the message as an argumant. i.e. node voxer.js "Voxer Message"
const threadID = 'ThreadID'
const fromID = 'UserID'
let cookie = `session={"gcp1-prod":{"user_id":"${fromID}","Rv_session_key":"RVSESSIONID"}}`
let time = new Date().getTime() / 1000
let messageID = new Date().getTime() + '_' + Math.floor(Math.random() * 10000000000 + 1000)

// Send message.
function sendMessage () {
  fetch(`https://gcp1-prod-nr60.voxer.com/2/cs/post_message?now=${time}`, {
    credentials: 'include',
    credentials: 'same-origin',
    headers: {
      'User-Agent': 'UserAgent',
      Accept: '*/*',
      'Accept-Language': 'en-US,en;q=0.5',
      'Content-Type': 'text/plain',
      'Sec-Fetch-Dest': 'empty',
      'Sec-Fetch-Mode': 'cors',
      'Sec-Fetch-Site': 'same-site',
      'sec-ch-ua-platform': '"Windows"',
      'sec-ch-ua': '"Opera";v="97", "Chromium";v="97", "Not=A?Brand";v="24"',
      'sec-ch-ua-mobile': '?0',
      Cookie: cookie
    },
    referrer: 'https://web.voxer.com/',
    body: `{\"message_id\":\"${messageID}\",\"create_time\":${time},\"model\":\"\",\"content_type\":\"text\",\"from\":\"${fromID}\",\"subject\":\"CHANGING\",\"body\":\"${body}\\n\",\"thread_id\":\"${threadID}\"}\r\n`,
    method: 'POST',
    mode: 'cors'
  })}

 sendMessage()

You can find the thread_id, user_id, session cookie by toggling the developer console, logging into Voxer, and send a message.

Creating a Simple systemd Service to Launch Shell Script on System Boot

We will setup a simple systemd service to automatically run a bash script on system boot.

Create systemd file

Create the service file with

vi /etc/systemd/system/multi-user.target.wants/bashscript.service

Now fill out the file. Change the Description and ExecStart. After= means only start this unit after the other units have finished. This is needed if we need to make a network connection. If our script runs before the network is up, the connection will fail.

[Unit]
Description=systemd Unit File to Launch Bash Script on System Boot
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target

[Service]
ExecStart=/home/user/script.sh

Change the ExecStart to your bash script and save the file

Enable systemd file

Now that the file is created, we need to enable the service so it starts on system boot

systemctl enable bashscript.service

You should get the following output.

Created symlink /etc/systemd/system/multi-user.target.wants/bash.service → /etc/systemd/system/bash.service.

Now to test, reboot your system, or start the service with

systemctl start bashscript.service

Auto Reboot Ubiquiti Devices with ubntmod.sh

Most of the heavy lifting is done by the ubntmod.sh script. All you need is the IP addresses for the access points. The script will figure out the connected devices, reboot them first, then reboot the AP.

Here is a quick run down of the steps we need to perform.

  1. Create list of AP’s and put them into an ap.lst file
  2. Install ubntmod.sh script
  3. Configure usernames and passwords to use with ubntmod.sh
  4. Setup crontab to automatically run

Create list of AP’s and put them into an ap.lst file

This is really as simple as creating the ap.lst file and filling it with the access point IP addresses. One per line. The script uses wstalist to discover connected devices.

nano ap.lst

Install ubntmod.sh script

Installing the script is really hard. 2 lines to get setup.

wget http://incredigeek.com/home/downloads/ubntmod/ubntmod.sh
chmod +x ./ubntmod.sh

More information can be found here.

https://www.incredigeek.com/home/ubntmod/

Setup usernames and passwords to use with ubntmod.shd

When you first run ubntmod.sh without the -y option, it should prompt you to setup usernames and passwords to use. After this is setup, the script automatically reads from the config file for future use.

You can manually modify the ubntmod.conf file update any usernames or passwords.

Example contents of ubntmod.conf file.

unpw=( "ubnt,ubnt"
"ubnt,password"
"admin,password"
)

Setup crontab to automatically run

Open up crontab with

crontab -e 

Configure the time. Refer to here for crontab date syntax

10 1 * * * cd /home/bob/ && ./ubntmod.sh -A

That’s it. Should be good to go.

Enable Automatic Update for Ubuntu Server 22.04

These steps should work for multiple versions of Ubuntu Server.

Thankfully enabling automatic updates in Ubuntu is super easy.

First make sure that the “unattended-upgrades” package is installed

sudo apt install unattended-upgrades

It was already installed on my Ubuntu 20.04 server instance.
Next run dpkg to reconfigure and enable updates

sudo dpkg-reconfigure unattended-upgrades

You should get the following prompt.

Configuring automatic updates

Hit “Yes” to enable.

Your system should now automatically install updates. however, if it needs to reboot it may not. You can configure the reboot options in

sudo vi /etc/apt/apt.conf.d/50unattended-upgrades

Scroll down to the Reboot lines and uncomment

// Automatically reboot *WITHOUT CONFIRMATION* if
//  the file /var/run/reboot-required is found after the upgrade
Unattended-Upgrade::Automatic-Reboot "true";  // <- Uncomment line

// If automatic reboot is enabled and needed, reboot at the specific
// time instead of immediately
// Default: "now"
Unattended-Upgrade::Automatic-Reboot-Time "02:00";  // <- Uncomment line

Save the file. Your system should now automatically install stable updates.

Disable automatic update

You can disable the automatic updates by running the dpkg command again.

sudo dpkg-reconfigure unattended-upgrades

and selecting “No”

Automatic updates should now be off.

More information can be found at the following link.

https://www.cyberciti.biz/faq/set-up-automatic-unattended-updates-for-ubuntu-20-04/

cnMaestro template for setting Username and Passwords for PMP gear

The following template can be used to set the user name and passwords for cambium pmp gear. Create a new template in cnMaestro, past in the following, change the passwordEncrypted to the hash of your password and run the config.

You can get the hashed password by pulling it out of a current radio config.

{
"userParameters": {
  "authenticationConfig": {
    "accounts": [ 
      { 
        "userName": "admin", 
        "level": 3, 
        "readOnly": false, 
        "passwordEncrypted": "188a934e0246ae248da19400fed83107a" 
      }, 
      { 
        "userName": "root", 
        "level": 3, 
        "readOnly": false, 
        "passwordEncrypted": "188a934e0246ae248da19400fed83107a" 
      } 
    ]
  }
 }
}

Upload ssh key to multiple servers automatically

Here is a quick script I created to automate copying a ssh key to multiple remote servers.

Basic command – the command uses sshpass to upload the ssh key to a remote server, this allows you to execute the command and not have to enter in a password to authenticate.

sshpass -p password ssh-copy-id -o StrictHostKeyChecking=no admin@remotehost

Script

#!/bin/bash

remotehosts="$1"
username="admin"
password="MyCoolPassword123"

for host in `cat ${remotehosts}`
do
sshpass -p${password} ssh-copy-id -o StrictHostKeyChecking=no ${username}@${host}
echo "Uploaded key to " ${host}
done

echo "Finished!"

 

Using the script

  1. Download here.
  2. Make it executable
    chmod +x sshcopy.sh
    
  3. Edit the script and change the username and password.
  4. Create a file that contains each host’s IP address or hostname.
  5. Run script (change hostlist.txt to your host list you created in step 3.)
    ./sshcopy.sh hostlist.txt
  6. Wait for the script to finish.

Example:

wget www.incredigeek.com/home/downloads/SSHCopy/sshcopy.sh
chmod +x sshcopy.sh
sed -i s/admin/bob/g sshcopy.sh                      <-- Change username - you can just manually edit the file,
sed -i s/MyCoolPassword123/password/g sshcopy.sh     <-- Change password - it might be easier than using sed
echo "192.168.1.100" >> host.txt                     <-- Add 192.168.1.100 to the host list
echo "Bob" >> host.txt                               <-- Add hostname bob to host list
./sshcopy.sh host.txt                                <-- Upload ssh key to all host's in the host file i.e. "bob" and "192.168.1.100"