Intro to Backups: How to Conduct Encrypted Backups Using Duplicity

You might be thinking “Asher, I’m in cybersecurity. Isn’t it the Sysadmin’s job to handle backups?”

Think back to the CIA triad: Confidentiality, Integrity, and Availability.

Backups certainly fall under Availability. You should know how your organization’s data is backed up, so you can protect it.

You should also know how the backups themselves work. Is the data encrypted in transit to the final destination? Are they encrypted on the final medium they’re resting on? Does the backup data have proper permissions? Is everything needed for a full recovery?

Before we move forward, I want to cover the “3-2-1 Backup Rule” concept.

image.png

Source: securityboulevard.com

There should be 3 copies of data, on a minimum of two different types of media. One of the copies should be offsite.

This is a good rule of thumb for protecting your data. However, the way you backup data will vary depending on your organization. Backing up a 5-million row database will differ from backing up a 10GB file system.

Let’s cover how you can perform a backup.

We’ll backup a directory with Duplicity, which is an open source software that:

provides encrypted, digitally signed, versioned, local or remote backup of files requiring little of the remote server. Released under the terms of the GNU General Public License (GPL)” (from their Wikipedia page.)

This tutorial will use Ubuntu 22.04.2 Desktop (Machine 1) and Ubuntu 22.04.02 Server (Machine 2.)

Let’s start with Machine 1. Install Duplicity:

image.png

Note: I’m using the 0.8.21-1 version.

We’ll create a separate user who exists just to do backups. Run these commands:

sudo useradd -m bkup -s /bin/bash
sudo touch /etc/sudoers.d/bkup
echo 'bkup ALL=NOPASSWD: /usr/bin/duplicity' | sudo tee -a /etc/sudoers.d/bkup

These lines:

  • Create a user named bkup with a home directory. This user’s login shell is /bin/bash.
  • Create a file named bkup at /etc/sudoers.d/
    • This file controls who can run what commands (specifically which users, on which machines)
  • Line 3 adds a rule to /etc/sudoers.d/bkup that says the bkup user can run the command “duplicity” as a root and without a password. This way, the backup user can access any file while using the duplicity command.

Now pivot to Machine 2. We need to create a backup user.

On Machine 2, run these commands:

sudo useradd -m bkup -s /bin/bash
sudo mkdir -p /opt/backups/duplicity
sudo chown bkup:bkup /opt/backups/duplicity
sudo mkdir /home/bkup/.ssh
sudo touch /home/bkup/.ssh/authorized_keys
sudo chmod 600 /home/bkup/.ssh/authorized_keys
sudo chown -R bkup:bkup /home/bkup/.ssh

We now have the backup user on Machine 2 and a location to put our backups. We also made a directory to store authorized SSH keys and assigned relevant permissions.

Head back to Machine 1. Change to the bkup user by running the command:

sudo -i -u bkup

Let’s setup a home environment with random files to backup.

mkdir -p ~/backup_me
touch ~/backup_me/make_random_files
chmod u+x ~/backup_me/make_random_files

Now vim ~/backup_me/make_random_files and add these lines:

#! /bin/bash
for n in {1..10}; do
dd if=/dev/urandom of=file$( printf %03d "$n" ).bin bs=1 count=$(( RANDOM + 1024 ))
done

This was taken from Stack Overflow. The script creates 10 files in the ~/backup_me directory with a random number of characters and text.

Before you run the script, make sure you’re in the ~/backup_me directory.

Now run the script.

image.png

You’ll have 10 files of random text in the backup_me directory!

image.png

GPG KEYS AND ENCRYPTION

Time to set up the keys we’ll use to encrypt the backups. We’ll use GPG, which is an open source alternative to Symantec’s PGP cryptography software.

Note: The reason I am not running the following commands as the bkup user is because of the way it asks for a password to protect the keys. See github.com/MISP/MISP/issues/3702.

We set up the bkup user with no password, so you can’t login as this user normally. This also allows me to show how to export and import keys, which is useful knowledge anyways.

First, make sure you’re not signed in as the bkup user. Then run gpg —gen-key to generate your keypair.

image.png

Time to export the keys and import them on the bkup user.

Run gpg –output /tmp/public.gpg –armor –export <email you used to create key here>.

For me the command is:

gpg --output /tmp/public.gpg --armor --export asher@mailfence.com

Then assign the correct permissions:

sudo chown bkup:bkup /tmp/public.gpg

Now switch to the bkup user and import the public key.

sudo -i -u bkup

Then use the GPG terminal to tell the system we trust the key:

gpg --import /tmp/public.gpg
rm /tmp/public.gpg
gpg --edit-key <email>
gpg> trust
gpg> 5
gpg> quit

Since we’re operating as the backup user, let’s create some SSH keys we’re going to need:

ssh-keygen -t rsa -m PEM

The terminal will ask you about which file to save the key, and a passphrase. Just press enter all the way through- it’ll use the defaults this way, which is what we want.

We now need to copy this key to Machine 2. It will enable SSH without passwords, which will make automation easier (we’ll get to this later.)

Run cat ~/.ssh/id_rsa.pub to get the ssh key. Copy it to clipboard.

On Machine 2

You need to paste the SSH key inside of /home/bkup/.ssh/authorized_keys.

To do this, we need to ssh into Machine 2. Run ifconfig on machine 2 to get the IP address.

Now run this command on Machine 1:

ssh <username_of_machine_2>@<ip_of_machine_2>

image.png

You’ll need to enter the password for Machine 2, then you’ll be in.

image.png

Change the user to bkup:

image.png

To paste the SSH key inside of /home/bkup/.ssh/authorized_key, you can simply head to the /.ssh directory, VIM the authorized_keys file, and paste the key in there.

image.png

Once you’ve done this, end the SSH connection and attempt to SSH again from Machine 1 (as the bkup user) to bkup@<machine_2_ip_address>. You should be able to SSH in without providing a password.

If the terminal asks you to add Machine 2 as a known host, say yes.

Nice work! Here’s what we’ve done so far:

  1. We created a user named bkup. We assigned it permissions to run the duplicity command as root.
  2. We created random files in our home directory to backup as a test.
  3. We created GPG keys to encrypt our backup on our machine before we send it to the destination (Machine 2.)
  4. We setup Machine 2 with the backup user, and we also setup a directory for the backups to go to.

Now we need to backup our ~/backup_me directory to Machine 2. Time to create a script that will handle doing this: As the bkup user on Machine 1, run these commands:

touch ~/backup.local

chmod u+x ~/backup.local

vim ~/backup.local

Add this to create the script:

image.png

Replace the SERVER_IP variable with the IP of Machine 2.

Replace BACKUP_FOLDER variable with the path that reflects your local machine, if you need to.

And lastly, fill ENCRYPT_KEY with your GPG key id. You can get this by running gpg —list-keys

image.png

Let me explain what this script is doing:

  • Backup to the Ubuntu server. Create a full backup if one doesn’t exist, or if the last full back is 2 weeks old.
  • Only keep up to 2 full backups.
  • Clean up any failures or messy files.
  • Show the results

Before we run the script, we need to configure the SSH server on Machine 2. Specifically, we need to setup sftp with the SSHD configuration for a directory titled opt/backups/duplicity/backup_me.

On Machine 2, follow these steps:

1. Install OpenSSH server: sudo apt-get install openssh-server

2. Create a new user: sudo adduser <username>

3. Create a new group named “sftpusers”: sudo groupadd sftpusers

4. Add the user you created to the sftpusers group: sudo usermod -a -G sftpusers <username>

5. Configure SSHD to use SFTP for the sftpusers group only: sudo nano /etc/ssh/sshd_config

6. Add the following lines to the end of the file:

  Match Group sftpusers
  ChrootDirectory /opt/backups/duplicity/backup_me
  ForceCommand internal-sftp
  X11Forwarding no
  AllowTcpForwarding no

7. Restart the SSHD service for the changes to take effect: sudo service ssh restart

Your SFTP server is now set up for the /opt/backups/duplicity directory and restricted to the sftpusers group only. Now you can use an SFTP client to connect to the server.

Head back to Machine 1. Run the script with:

~/backup.local

image.png
image.png

You’ll be asked for a GnuPG passphrase for decryption. That’s the passphrase you set upon creating the keypair.

Now SSH into the Ubuntu server, and head to the /opt/backups/duplicity/backup_me directory. You’ll see your backup!

image.png

In Part II, we’ll cover how to backup offsite, restore the backups, and add additional automation.

Thanks for reading!