Why?
Lets start off with a few notes about how and why I would do this. I already have a fireproof/waterproof drive in my house. Sounds like im all set right? Not really.
Although im set on a disaster level there are a few things that can be an issue with onsite backups. Especially with my drive being plugged in all the time.
- Theft, Although it is “theft resistant” the metal they want me to bolt down isnt very strong at all. Anyone with half a brain can break it in about 1 minute with all the tools I have down there.
- Hackers, In recent times most of these hacks have targeted user data by encrypting the entire set of data and holding it hostage for bitcoin.
- Accidents, They happen all the time to people. Commands like
rm -rf ./*
or even formatting the wrong partition. Lets just not set ourselves up for failure.
How?
Who in the world is gonna host my raspberry pi that I can trust? Are they gonna try and charge me for electric? Are they going to want an internet fee? Will I slow down the wifi?
Trust?
We dont actually need to trust them all that much, They dont need any passwords and we dont even risk our data becouse we plan on using encryption.
Electric?
The raspberry pi is device that runs on arm, luckly smartphones also run on arm which makes them ideal for super low power usage. By stripping down a raspberry pi we can get the power usage so low that they wont even care about the half dollar its going to cost them montly. Toss them a $20 and call yourselves even for like 3-4 years.
The Math:
Currently my setup consists of idle usage of about 800mah with two USB drives attached and a micro sd card. You could probably go lower by eliminating the second usb but i dont really trust the micro sd card I attached to long live, also its 2gb haha.
- 800mah * 5v = 4w
- 4w * 24hrs * 30 days = 2880wh/month
- 2880wh * $0.15/kw = $0.43/Month
Internet?
As long as your not daily downloading extremely large amounts of data daily then you should be fine. I dont backup my media library, I can get those back easy. What i do backup is my nextcloud setup with all my personal family photos/videos and documents on my server.
To avoid hogging the network I set the backup to run daily at a time that I know they wont be on, like 4AM.
Wifi?
You should avoid wifi at all costs, You will increase your power usage and theres more benefit to using ethernet for reliability.
Prerequisites
Before you get going you will need to install Rasbian on a micro sd card. For my setup I installed it on a USB drive as well which is entirely optional for reliability. You may want to minimize your setup, just skip the part about wifi.
Hardware:
- Raspberry Pi Model B with Raspian on SD card
- 16GB Sandisk USB with Raspbian
- 4TB Western Digital My Passport Ultra USB3 Hard Drive
- HooToo Powered USB3 Hub (optional)
USB hard drives are great however becouse they dont use external power bricks you may see some issues if your pi cant provide enough power. You can try this hub to power both the Pi and the HDD.
Setup drive
Install cryptsetup to encrypt drives.
pi@raspberrypi ~ $ sudo apt-get install cryptsetup
Find your disk
Find the /dev identifier of the HDD partition you want to encrypt, on my system, it’s /dev/sdb1. Note that this output is from running the command after I’ve configured the encrypted partition.
pi@raspberrypi ~ $ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb 8:0 0 3.6T 0 disk
Create partition
Start by creating a partition with fdisk.
sudo fdisk /dev/sdb
- Press
n
option to create a new partition - Press
p
for a primary partition. - Press
1
to edit the first partition - Press
ENTER
twice to use the defaults for first and last sectors - Press
w
to save changes to disk - Press
q
to quit
It will look similar to this:
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-3906916350, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-3906916350, default 3906916350):
Created a new partition 1 of type 'Linux' and of size 4.3 TiB.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Encrypt the partition
sudo cryptsetup -v -y -c aes-xts-plain64 -s 512 -h sha512 -i 5000 --use-random luksFormat /dev/sdb1
The options of the command are as follows:
-v
= verbose-y
= verify passphrase-c
= cipher used-s
= key size used-h
= hash used-i
= number of ms to spend passphrase processing--use-random
= which random number generator to useluksFormat
= initialize the partition and set a passphrase/dev/sdb1
= partition to encrypt
Optionally you can backup the luks header.
Add secondary keyfile for stdin use
To use luks remotely we will need to add a keyfile to the luksheader. nano keyfile
and put a random key in here, it can even be the same as your passphrase.
sudo cryptsetup luksAddKey /dev/sdb1 keyfile
Dont forget to delete that keyfile otherwise your setup will be exposed. rm keyfile
Format the volume
Mount the luks device and format the volume
sudo cryptsetup luksOpen /dev/sdb1 volume01
sudo mkfs.ext4 /dev/mapper/volume01
Mounting the volume
You can mount it anywhere but for this setup we will mount it to /mnt/raid
sudo mkdir -p /mnt/raid
sudo mount /dev/mapper/volume01 /mnt/raid
You should now be able to see it under df -h
Unmount and close
sudo umount /mnt/drive01
sudo cryptsetup luksClose /dev/mapper/volume01
DDNS
You will need to install some utilities for this.
apt install curl dnsutils
Create a script file with the following but change your.domain.name
and the ddns update url with your own.
nano /home/pi/ddns.sh
#!/bin/bash
IP_NS=$(dig +short your.domain.name)
IP_WAN=$(curl -ks http://checkip.amazonaws.com/)
if [[ "$IP_NS" == "$IP_WAN" ]]; then
echo "No IP update required. ($IP_WAN)"
else
echo "IP has changed from ($IP_WAN) to ($IP_NS)"
curl -ks https://dnsprovider.com?key=sometokentochangeip
fi
Now add the script to your crontab after making it executable
chmod +x /home/pi/ddns.sh
crontab -e
*/10 * * * * /home/pi/ddns.sh
You can also have it run when ethernet is up with the following command
sudo ln -s /home/pi/ddns.sh /etc/network/if-up.d/ddns
upnp port forwarding
Becouse some routers dont allow ports below 1024 to be mounted we will just be opening up ssh to another port. View a more detailed writeup on how to run this on ethernet connect.
sudo apt install miniupnpc
You can change port 1080 to anything you desire, it is recommended to keep it above 1024 for some routers that dont allow numbers below that.
nano /home/pi/upnp.sh
#!/bin/bash
ip=$(upnpc -l | grep "Local LAN ip address" | cut -d: -f2)
upnpc -e "Backups" -a $ip 22 1080 TCP
chmod +x /home/pi/upnp.sh
You can have it run when ethernet is up with the following command
sudo ln -s /home/pi/upnp.sh /etc/network/if-up.d/upnp
Script mounting
Install some utilities needed for this script and make sure you have at least tried to ssh once to grab the fingerprint
apt install sshpass
Now on your remote client create a script to start the backups
nano remote-backup.sh
#!/bin/bash
#Use blkid to find this for your device
DRIVE_UUID=5bced688-7fa8-48b8-ad59-d63fe8aa14d5
#Device credentials
HOST="raspberrypi.yourdomain.com"
USERNAME="pi"
PASSWORD=""
#keyfile string used to decrypt drive
PASSPHRASE=''
#Path on local to backup to remote with trailing slash
BACKUP_PATH="/mnt/raid/home/"
echo "Connecting to pi"
sshpass -p $PASSWORD ssh $USERNAME@$HOST << EOF
echo "Mounting drive"
sudo mkdir /mnt/backup
echo '$PASSPHRASE' | sudo cryptsetup luksOpen /dev/disk/by-uuid/$DRIVE_UUID volume01 -d=-
sudo mount /dev/mapper/volume01 /mnt/backup
sudo chmod 777 /mnt/backup
EOF
echo "Run rsync"
sshpass -p $PASSWORD rsync -avzr --delete -P -e ssh $BACKUP_PATH $USERNAME@$HOST:/mnt/backup/
echo "Unmount the drive"
sshpass -p $PASSWORD ssh $USERNAME@$HOST << EOF
sudo umount /mnt/backup
sudo cryptsetup luksClose /dev/mapper/volume01
EOF
Now lets make this run once a week on sunday at midnight with crontab -e
0 0 * * 0 /path/to/remote-backup.sh
Save your passphrase and keyfile somewhere safe, Lastpass, Fireproof safe, the cloud. Just remember that if your local copy goes away or you get robbed you will need that key to decrypt the remote copy.
Now you are all set for weekly backups. You can add more cronjobs to delete data weekly or do nightly backups as well. If you have any edits feel free to hit the edit button on the bottom of the article or leave a comment.