Return to Main Page


Turning Your Router into Backup Facility


I have VPS hosting several web sites under LEMP stack (SERVER). The provider charges extra cost for backup copies and I decided to spare expense by using my home router as a backup host (BACKUP). BACKUP is ASUS RT-N10U router with Oleg’s firmware installed. I have not tested but believe that below will work on DD-WRT, Open-WRT or similar Linux-based firmware.

Traditionally this is achieved by launching rsync utility on SERVER like:

~# rsync -avz root@SERVER:/dir/to/copy /local/folder/backup

It doesn’t completely suit my needs as I have restricted to or like to:

  1. Backup the data with dynamic IP
  2. Minimize backup space by archiving data and updating only the changed files

Step 1

As a prerequisite you have to install zip, unzip and rsync packages on your USB drive under /opt directory:

~# ipkg install zip
~# ipkg install unzip
~# ipkg install rsync


Step 2

Create public/private key pair for passwordless shell access. Get shell access to SERVER. Create ssh authorization key pair by:

~# mkdir ~/.ssh
~# cd ~/.ssh
~# ssh-keygen -t rsa

This should create two files id_rsa.pub (public key) and id_rsa (private key). Append the content of the public key to the authorized_keys file in you ssh directory.

~# cat ./id_rsa.pub >> ./authorized_keys && rm ./id_rsa.pub

Now we have to put the private key to BACKUP host. Get shell access to BACKUP and download the private key from the SERVER:

~# mkdir ~/.ssh
~# cd ~/.ssh
~# scp root@SERVER:/root/.ssh/id_rsa ./id_rsa.db

Since dropbear ssh client uses its own key format you have to convert the copied key by:

~# dropbearconvert openssh dropbear ./id_rsa.db ./id_rsa.db

You can test how you key works by issuing command from BACKUP that will delete the already copied private key on SERVER. Now you don’t have to enter any password.

~# ssh -i "./id_rsa.db" root@SERVER "cd /root/.ssh; rm ./id_rsa"


Step 3

#!/bin/bash

KEY="/usr/local/root/.ssh/id_rsa.db"
REMOTE="root@SERVER"
DIRS="/home/dir1 /home/dir2 /dir3 /mnt/shared/dir4"
BKUP="/tmp/mnt/backup/"
OPT="/opt/bin/"

ssh -i $KEY $REMOTE "find $DIRS -ctime -1" | ${OPT}rsync -avz -e "ssh -i $KEY" --files-from=- $REMOTE:/ $BKUP

${OPT}zip -murT ${BKUP}backupdata.zip ${BKUP}*

exit 0

In this script we first get the list of all files in the target directories changed in last 24 hours (-ctime -1). Change according to your needs. All selected files are copied by rsync to the backup directory. Then the program updates the zipped archive file (backupdata.zip) and cleans the downloaded data.


Step 4

If you need to make regular backups you need to create a cronjob for your script. Edit you crontab and add the following line.

0 5 * * * /usr/local/sbin/rsync.sh

This is to make daily snapshots at 5 am. Change according to your needs. Now if you check the script it surprisingly will not work. There are several reasons it fails:

  1. Firmware embedded cron has its own hard coded PATH variable, that as I understood you cannot change. It doesn’t contain /opt/bin directory where rsync, zip and unzip executables binaries are located. Adding absolute paths will solve it.
  2. Dropbear ssh client needs STDIN opened in order to work with STDOUT. Cron doesn’t automatically open STDIN in contrast with shell. We have to create STDIN explicitly with /dev/zero redirection.
  3. When zip tests the archive it compares each expanded file checksum with the original one stored in the archive. For this purpose unzip is launched by default with -tqq options. Unzip utility located in directory that is not listed in the PATH variable (see above). To solve the issue we have to add additional option to point to unzip command /opt/bin/unzip.

Now the final script modified for cronjob will look like this:

#!/bin/bash

KEY="/usr/local/root/.ssh/id_rsa.db"
REMOTE="root@SERVER"
DIRS="/home/dir1 /home/dir2 /dir3 /mnt/shared/dir4"
BKUP="/tmp/mnt/backup/"
OPT="/opt/bin/"

ssh -i $KEY $REMOTE "find $DIRS -ctime -1" < /dev/zero | ${OPT}rsync -az -e "ssh -i $KEY" --files-from=- $REMOTE:/ $BKUP

${OPT}zip -murT ${BKUP}backupdata.zip ${BKUP}* -TT "${OPT}unzip -tqq"

exit 0

August 13, 2015