Skip to content

Instantly share code, notes, and snippets.

@kirsle

kirsle/README.md

Created Mar 19, 2020
Embed
What would you like to do?
Offsite Encrypted Backups

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.

Install cryptsetup: 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 root@example.com './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 root@example.com './luks-umount.sh'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.