Saturday, 6 July 2019

Raspberry Pi Backup Server

Getting Old

Recently I've found myself lying awake at night worrying if my documents, code and photos are backed up and recoverable. Or to put it another way - I've officially become old :-(

With a new Raspberry Pi 4B on order it's time to re-purpose the old Raspberry Pi 3B to create a backup solution.


I want my backup solution and backup media to be small, cheap and redundant. Speed isn't really an issue, so I've chosen micro SD as my backup media for this project.

I've picked up an Anker 4-Port USB hub, 2 SanDisk 64 GB micro SD cards and 2 SanDisk MobileMate micro SD card readers. I ordered this kit from Amazon and the prices at the time of writing were:

Anker 4-Port USB 3.0 Ultra Slim Data Hub £10.99
SanDisk Ultra 64 GB microSDXC £11.73
SanDisk MobileMate USB 3.0 Reader £7.50

They fit together really well, with room for two more SD cards and readers if I need to expand:

The plan is to make one of the SD cards available over the network as a share, via the Pi using SAMBA. The share can be mapped as a Windows network drive and files can easily be dragged and dropped for backup. In case the first backup SD card fails, the Pi will copy the files and folders from the first SD card to the second SD card using rsync to create a backup of the backup.


Download and upgrade the Pi 3B to the lastest version of Raspbian. I've chosen Rapbian Lite to save a bit of space on the Pi's SD card:

At the time of writing the lastest download was:

Write the OS to the Pi's SD card using Etcher. Top tip - Etcher can write a .zip file, but it's much quicker to extract the .iso file from the .zip file and write that instead.

Don't forget to add an empty ssh file to the boot partition on the Pi's SD card if you are going to run the Pi headless.

Put the Pi's SD card into the Pi, attached the USB hub and micro SD cards, and boot the Pi and login via SSH. Update and upgrade any new packages first, enable unattended security updates and install your editor of choice:

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install unattended-upgrades
$ sudo apt-get install vim

Because I've got a Pi 4 on the way, I want to call this Pi 'raspberrypi3'. Modify the /etc/hostname and /etc/hosts files:

$ sudo vim /etc/hostname

$ sudo vim /etc/hosts       raspberrypi3
$ sudo reboot

At this point, the backup SD cards should be available to Linux as devices /dev/sda and /dev/sdb.

I want the backup SD cards to be readable on Linux and Windows machines using the exFAT file system. A good tutorial on how to do this on Linux using FUSE and gdisk is available here:

$ sudo apt-get install exfat-fuse exfat-utils
$ sudo apt-get install gdisk

Use gdisk to remove any existing partitions, create a new partition and write this to the SD cards. Make sure to create the new partition as type 0700 (Microsoft basic data) when prompted:

$ sudo gdisk /dev/sda

GPT fdisk (gdisk) version 0.8.8

Partition table scan:
  MBR: not present
  BSD: not present
  APM: not present
  GPT: not present

Creating new GPT entries.

Command (? for help):
Command (? for help): o
This option deletes all partitions and creates a new protective MBR.
Proceed? (Y/N): Y
Command (? for help): n
Partition number (1-128, default 1):
First sector (34-16326462, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-16326462, default = 16326462) or {+-}size{KMGTP}:
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 0700
Changed type of partition to 'Microsoft basic data'
Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING

Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/sda.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot.
The operation has completed successfully.

Repeat for the second SD card:

$ sudo gdisk /dev/sdb

Create exFAT partitions on both SD cards and label the partitions PRIMARY and SECONDARY:

$ sudo mkfs.exfat /dev/sda1
$ sudo exfatlabel /dev/sda1 PRIMARY
$ sudo mkfs.exfat /dev/sdb1
$ sudo exfatlabel /dev/sdb1 SECONDARY

Create directories to mount the new partitions on:

$ sudo mkdir -p /media/usb/backup/primary
$ sudo mkdir -p /media/usb/backup/secondary

Modify /etc/fstab to mount the SD cards by partition label. This allows us to mount the correct card regardless of it's device path or UUID:

$ sudo vim /etc/fstab

LABEL=PRIMARY /media/usb/backup/primary exfat defaults 0 0
LABEL=SECONDARY /media/usb/backup/secondary exfat defaults 0 0

Mount the SD cards:

$ sudo mount /media/usb/backup/primary
$ sudo mount /media/usb/backup/secondary

Create a cron job to rsync files from the primary card to the secondary card. The following entry syncs the files every day at 4am:

$ sudo crontab -e

0 4 * * * rsync -av --delete /media/usb/backup/primary/ /media/usb/backup/secondary/

To sync files immediately, rsync can be run from the command line at any time with:

$ sudo rsync -av --delete /media/usb/backup/primary/ /media/usb/backup/secondary/

To make the primary SD card available as a Windows share, install and configure SAMBA:

$ sudo apt-get install samba samba-common-bin
$ sudo vim /etc/samba/smb.conf

   comment = Pi backup share
   path = /media/usb/backup/primary
   public = yes
   browseable = yes
   writable = yes
   create mask = 0777
   directory mask = 0777

$ sudo service smbd restart

Finally, install and configure UFW firewall, allowing incoming connections for SSH and SAMBA only:

$ sudo apt-get install ufw
$ sudo ufw default deny incoming
$ sudo ufw default allow outgoing
$ sudo ufw allow ssh
$ sudo ufw allow samba
$ sudo ufw enable