I needed a backup solution for my home NAS (QNAP), and preferably, it should be an offsite backup. My NAS only have one disk slot, so for obvious reasons it cannot support RAID, but even if it did support RAID, it would only protect my data from disk failure. RAID cannot protect my data from a house fire or lightning strike nor theft of the actual NAS. This would be assured by having an offsite backup. Now why did I not just use one of the could services, which already are integrated in the NAS? Well, for two reasons – First, I do not like the idea of my data stored in a cloud service, and secondly I love to play with these things. 🙂
In order the keep the cost low, I choose to build the solution on a Raspberry Pi and a 2 TB USB hard drive, which is less expensive than the cheapest NAS I could find. Both my NAS and the Pi supports RSYNC, so this will be the transfer and synchronization application. The data needs to be encrypted in transit, so it can be transferred on the Internet. Rsync can use SSH to do this, but this would expose my NAS to the public internet. I could restrict the access in my firewall, but this would require the remote site to have a known static IP address. Since I will place the offsite backup at some of my relatives, this will not work, as they do not have a static IP. The encrypted access is therefore done by Remote Access VPN to my Cisco ASA firewall.
The configuration of the NAS is simple and is all done by the web interface. Logon the system, and go to Control Panel –> Applications –> Backup Server –> Rsync server.
Enable backup service and allow remote Rsync to backup data, and set the username and password which will be used for this.
That’s it for the NAS.
Download the latest Raspbian distribution and write it to a SD card which does not have to very large. Boot up the Pi and run initial configuration from the wizard.
Next, update the Pi before continuing
sudo apt-get update sudo apt-get upgrade
The network configuration are default to DHCP and I will keep it this way, since I want this solution to be flexible and moveable.
USB Drive configuration
Attach the USB Hard drive
Plug the hard drive into the Pi and verify that the Pi have found the disk
Use fdisk to partition the disk and use mkfs to format it.
sudo fdisk /dev/sda sudo mkfs.ext4 /dev/sda1
Create a folder to mount the HDD in
sudo mkdir /mnt/USBHDD01
Find the UUID for the disk
ls -l /dev/disk/by-uuid/
Then update the /etc/fstab with the disk and mount point. I choose to NOT auto mount the disk, because when the disk is mounted it has constant activity, which wears the disk unnecessarily since it most of the time just will sit idle from a backup perspective. Another reason is that if the backup station will experience a power outage and the disk is dismounted, it will not be a problem to the file system. The backup script will just mount and dismount the disk as needed.
--- output omitted --- UUID=f6fa5238-3055-4db7-9665-a6568f86db84 /mnt/USBHDD01 ext4 defaults,noauto 0 0
Now the disk is ready to use.
Install the Remote Access VPN client
vpnc is a CLI VPN client for ‘nix systems, and it is available for Raspbian. The vpnc will connect to the Cisco ASA I am using as edge firewall and form an IPsec remote access tunnel.
sudo apt-get install vpnc
The connection have to be configures before it can be used. First, make a copy of the template located in /etc/vpnc/default.conf
sudo cp /etc/vpnc/default.conf /etc/vpnc/MYVPN.conf
The content of the file will like the following – adjust for your VPN configuration
IPSec gateway vpn.xxxx.eu IPSec ID MY-TUNNELGROUP IPSec secret presharepa$$w0rd Xauth username USER Xauth password pa$$w0rd
You can verify the VPN connection is working as expected
sudo vpnc-connect MYVPN
To make the Pi able to send emails install ssmtp.
sudo atp-get install ssmtp
Configure ssmtp to use an email account through the configuration file in /etc/ssmtp/ssmtp.conf
I have added the following to the standard configuration
AuthUserfirstname.lastname@example.org AuthPass=mysecret FromLineOverride=YES mailhub=smtp.domain.com UseSTARTTLS=YES
When you send mails the system will use the actual username of the logged in user and the hostname of the system. This will probably no work with most email providers. This can be changed by creating an alias in the file /etc/ssmtp/revaliases. The script will run as root when scheduled, so I have created the alias for the root user account.
I wrote a small script that puts all the pieces together. The script mounts the backup disk, brings up the VPN tunnel and uses Rsync to synchronize the backup disk with the NAS. It writes messages to the local syslog and sends an email, so I can verify that the backup has completed without errors.
#!/bin/bash # RSYNC NAS Backup script by Bo Urskov - bourskov.dk # # Feb 2015 # NAS settings VPN_GATEWAY="MYVPN" RSYNC_SERVER="192.168.10.8" MAILRCPT="email@example.com" USERNAME="backupuser" export RSYNC_PASSWORD=thisisasecret # Write to local syslog logger -t NAS-BACKUP started... # Mount Backup HDD echo Mounting Backup HDD... if mount /mnt/USBHDD01 ; then echo Mounted USBHDD01... else echo ERROR! Cannot mount backup disk! logger -t NAS-BACKUP ERROR! Cannot mount backup disk! ssmtp -F"BACKUP-PI" $MAILRCPT < /home/pi/MSG-BACKUP-ERROR.txt exit 1 fi # Get VPN connection echo Bringing up VPN tunnel... if vpnc-connect $VPN_GATEWAY ; then echo Connected... else echo ERROR! Cannot bring tunnel up! logger -t NAS-BACKUP ERROR! Cannot bring tunnel up! ssmtp -F"BACKUP-PI" $MAILRCPT < /home/pi/MSG-BACKUP-ERROR.txt exit 2 fi # Verify connectivity to RSYNC Server echo Verify connectivity to NAS... if ping $RSYNC_SERVER -c 2 ; then echo NAS responds to pings... else echo ERROR! No connectivity to NAS! logger -t NAS-BACKUP ERROR! No connectivity to NAS! ssmtp -F"BACKUP-PI" $MAILRCPT < /home/pi/MSG-BACKUP-ERROR.txt exit 3 fi # Do the backups echo Syncing: tftproot rsync -aP --delete $USERNAME@$RSYNC_SERVER::tftproot /mnt/USBHDD01/tftproot echo Syncing: Billeder rsync -aP --delete $USERNAME@$RSYNC_SERVER::Billeder /mnt/USBHDD01/Billeder echo Syncing: Multimedia rsync -aP --delete $USERNAME@$RSYNC_SERVER::Multimedia /mnt/USBHDD01/Multimedia echo Syncing: data rsync -aP --delete $USERNAME@$RSYNC_SERVER::data /mnt/USBHDD01/data echo Syncing: ISO rsync -aP --delete $USERNAME@$RSYNC_SERVER::ISO /mnt/USBHDD01/ISO echo Syncing: Privat rsync -aP --delete $USERNAME@$RSYNC_SERVER::Privat /mnt/USBHDD01/Privat # Disconnect VPN connection echo Disconnecting VPN... vpnc-disconnect # Wait a few secs before dismounting backup disk echo Waiting 2 seconds before dismounting backup disk... sleep 2 # Dismount Backup HDD if umount /mnt/USBHDD01 ; then echo Dismounted USBHDD01... else echo ERROR! logger -t NAS-BACKUP ERROR! Cannot dismount disk exit 2 fi # Backup completed logger -t NAS-BACKUP Backup completed ssmtp -F"BACKUP-PI" $MAILRCPT < /home/pi/MSG-BACKUP-OK.txt
Schedule the backup task
The last thing is to schedule the backup job in cron. The script will run as root, so I just edited the file /etc/crontab and scheduled it to run every night.
# m h dom mon dow user command 0 0 * * * root /home/pi/nas-backup.sh
All in all, a neat and cheap solution for offsite backup of my QNAP NAS… 🙂