This describes my setup for using DigitalOcean Volumes (disk images attached to my VPS) for off-site backups and keeping them encrypted-at-rest when I'm not actively writing or reading to the disk image.
Basically it consists of:
- A DigitalOcean virtual private server.
- An extra Volume attached to the VPS (100GB or so), this presents itself as a block storage device in Linux.
- LUKS encrypted partition on the Volume.
- A few shell scripts to mount, rsync, and unmount the volume.
Initial Setup (One Time)
These steps are only done in the beginning to initially format and set up the encrypted disk partition.
sudo apt install cryptsetup or
sudo dnf install cryptsetup-luks for Debian or Fedora.
Create a partition table and a partition on the disk you're using (i.e. so that /dev/sda is the hard disk and /dev/sda1 is the first partition on it). Filesystem on the partition doesn't matter because it's going to be overwritten anyway.
Format the partition for LUKS encryption:
cryptsetup -y -v luksFormat /dev/sda1
Open the LUKS volume and give it a mapper name ("backup" in this example):
cryptsetup luksOpen /dev/sda1 backup
This creates the device node
/dev/mapper/backup which represents the
decrypted partition, so you can create a filesystem on it and mount it:
# Create an ext4 filesystem in the LUKS volume. mkfs.ext4 /dev/mapper/backup # Mount it. mkdir -p /mnt/backup mount /dev/mapper/backup /mnt/backup
To unmount and close the encrypted volume for data security at rest:
# Unmount umount /mnt/backup # Lock the encrypted partition. cryptsetup luksClose backup
Mounting and Unmounting the LUKS Partition
To manually decrypt and mount, and unmount and lock again, the commands would be as follows:
# Decrypt and mount cryptsetup luksOpen /dev/sda1 backup mount /dev/mapper/backup /mnt/backup # Unmount and lock umount /mnt/backup cryptsetup luksClose backup
The Backup Scripts
Putting it all together, I wrote a few shell scripts to automate the backup process as much as possible.
From my client device I just run a shell script, enter my LUKS disk encryption password, and it rsync's over and locks the disk when done.
Server Side Mount/Unmount Scripts
/root/luks-mount.sh to decrypt and mount the filesystem:
#!/bin/bash if [[ -f "/mnt/backup/mounted.txt" ]]; then echo LUKS disk is already mounted. exit 0 fi cryptsetup luksOpen /dev/sda1 backup mount /dev/mapper/backup /mnt/backup df -H
NOTE: I created an empty file "mounted.txt" in the filesystem to easily check whether the disk is mounted or not. The above shell script checks its existence before attempting to unlock the disk.
/root/luks-umount.sh to lock the disk back down:
#!/bin/bash if [[ ! -f "/mnt/backup/mounted.txt" ]]; then echo LUKS disk is already unmounted. exit 0 fi umount /mnt/backup cryptsetup luksClose backup
Client Side Script
This is the one I actually run when I need to sync my backups to my remote server.
Note: set up SSH key based authentication to make it easier. When you run the backup script you're only prompted to enter the LUKS disk password and the rest of the script is automatic.
#!/bin/bash # Exit on first error. set -e # Mount the remote LUKS volume. echo Mounting remote crypto-backup LUKS volume on example.com... ssh -t firstname.lastname@example.org './luks-mount.sh' # Rsync your stuff over. echo Copying backups over... rsync -av /mnt/Midnight/Images/Organized/ example.com:/mnt/crypto-backup/Photos/ # Lock the disk when finished for encryption at rest. echo Unmounting remote LUKS volume ssh -t email@example.com './luks-umount.sh'