Skip to content

Instantly share code, notes, and snippets.

@smcalilly
Last active February 19, 2021 05:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smcalilly/79b52fc54aa932cc6b222c67023f99d4 to your computer and use it in GitHub Desktop.
Save smcalilly/79b52fc54aa932cc6b222c67023f99d4 to your computer and use it in GitHub Desktop.

backupper

I was tired of my SD cards corrupting on my Raspberry Pis and rebuilding the system from an old, out-of-date backup image, so here is a homemade backup strategy for my backup images.

Each machine has a user called backupper and each backupper user has the ability to copy disk images to each other's /backupper/backups directory. The computers do the exact same thing to each other, but the opposite.

  • backupper@computer_tina creates an encrypted, compressed disk image of itself and securely sends the file to backupper@computer_okie:/home/backupper/backups/computer_tina
  • backupper@computer_okie creates an encrypted, compressed disk image of itself and securely sends the file to backupper@computer_tina:/home/backupper/backups/computer_okie

My head hurts and my eyes are cross.

If you want, you can use borg backup to send the images to a remote borg repository. You could use borg to back up your files, too, but I like to have a Raspberry Pi image lying around with all my configurations saved so I don't have to go through that pain when the card corrupts or I want to try something new on another machine. With this strategy, you can backup your images and use a borg repos to backup the directory with those images.

how to do this

Do each of these commands in both machines. There might be some cds and such missing in some places (sorry!), so do your best to fill in the gaps. It's easiest to do the same command, step-by-step, together, in each machine, as you go. Just open two terminals and copy/paste. I wrote these commands down so I won't forget them, but decided to share. Let me know if you get stuck and maybe I can help.

backupper user

Create a backupper user with a home directory:

sudo useradd -m backupper

Give backupper a password:

sudo passwd backupper

Login with backupper and cd into backupper's home directory

su backupper
cd ~/backupper/

Try and use sudo with backupper. You should get a permission denied error.

sudo less /etc/shadow

setup the directory for backups

Create a directory for your backups:

cd backupper && mkdir backups/self && mkdir backups/$remote_host
touch .backup.sh

This should create a a directory at /backupper/backups/self and /backupper/backups/$remote_host.

/backupper/backups/$remote_host is where the images from your other computer friend will live. ~/self can be where you save the local machine's image, if you want. You can name these directories whatever you want or even hide them somewhere, just change the names in the script — we'll come back and add code to .backup.sh later.

setup ssh

Gotta swap public keys between the two backupper users. This part is kinda tricky, so pay attention to what you're doing. Digital Ocean has some good information if you get stuck here.

An important thing to know: you need to be logged into to both backupper users when you create the keys so that the correct users are owners of the ~/.ssh code. I learned this the hard way.

ssh public keys

You should still be logged into your backupper users. Create keys with each backupper user:

ssh-keygen -t rsa

Print the public key for backupper@local and copy it to your clipboard:

cd backupper/.ssh
cat id_rsa.pub

Add the public key to backupper@$remote_host:

echo "$key_from_clipboard" > authorized_keys

Make sure the keys match for either set of keys. Compare the authorized keys in the remote host:

# remote host
cat authorized_keys

# client -- should match the remote host's authorized keys
cat id_rsa.pub

give backupper ssh permissions

backupper needs to be added to the sshusers group:

sudo usermod -a -G sshusers backupper

Restart ssh service:

sudo systemctl reload sshd.service

If you want to really lock down, you can limit what a ssh public key can do or access.

limit backupper's user permissions

Logout of backupper with exit. cd into the backupper/backups directory.

With the superuser, only give the script owner (backupper) read and execute permissions:

sudo chmod 0500 .backup.sh

Confirm that the backupper user can't write to the script. Other users can't read the script. A superuser can read, write, and execute.

Edit the sudo file with a superuser:

sudo visudo

Add these lines to the file:

# blacklist everything
backupper ALL=(ALL) !ALL

# whitelist only what you need
backupper ALL=NOPASSWD: /bin/dd

add the backup code

Add this code to backupper/backups/.backup.sh. It's not much code and you can probably take it to a better place if you tried.

local_backup_path=/home/backupper/backups/self
local_backup_target=$local_backup_path/$HOSTNAME.$(date +%d%m%Y).img.gz
remote_backup_target=backupper@$remote_backup_host:~/backups/$HOSTNAME

# backup
sudo dd if=/dev/mmcblk0 conv=sync,noerror status=progress | openssl aes-192-cbc -salt -e -pass "pass:password" | gzip -9 -c > $local_backup_target

# copy to remote hosts
scp $local_backup_target $remote_backup_target

# delete your local image, if you want.
# you should also figure out a way so that
# the remote host isn't full of your images
rm $local_backup_target

run the script

Make sure you're logged in as a backupper user to run it:

./backups/backup.sh

Watch the status of the dd command:

watch -n 10 ls -alh

This can take a long time. You should have a backup in your remote host eventually. For initial testing, you might want to halt this process and then comment out line with the dd command, so you can test the scp. If your ssh is properly configured, then this should work, but you might have some headaches here.

Let me know how I can improve this, particularly the script that does the image backup. And if anybody actually knows how to use linux like a sysadmin would professionally, please let me know ways in which this could be improved or go wrong or if I'm doing anything counterintutively.

troubleshooting

If you have any issues, good luck. Your pain points might be ssh, backupper's user permissions, copying the image with dd, scp, etc. Pick a part each piece and figure out what is and is not working, then figure out why that part is not working.

some helpful commands

I'm a linux noob, especially with users and permissions, so here are some bash ingredients that I kept nearby while working on this.

list all users

less /etc/passwd

delete user

sudo userdel backupper

see user's groups

groups

ssh config

sudo nano /etc/ssh/sshd_config

ssh logs

tail -n 500 /var/log/auth.log | grep 'sshd'

to-do

  • You're gonna need to delete old backups somehow
  • Limit what an SSH user can do within the backupper user

resources

@smcalilly
Copy link
Author

smcalilly commented Feb 17, 2021

create this script to run in the backup directory

#!/bin/bash
# 
# this script creates a backup image of a raspberry pi and
# copies the backup image to a remote host
#
# thanks: https://blog.galt.me/automatic-raspberry-pi-backups/
# & https://github.com/AdamGalt/Auto-Pi-Backup
#


days_to_keep_locally=14
local_backup_path=/home/backupper/backups/self
local_backup_target=$local_backup_path/$HOSTNAME.$(date +%d%m%Y).img.gz
remote_backup_host=ssd
remote_backup_target=backupper@$remote_backup_host:~/backups/$HOSTNAME

# Backup
sudo dd if=/dev/mmcblk0 bs=1M status=progress | gzip > $local_backup_target

# Copy to remote hosts
scp $local_backup_target $remote_backup_target

# Clean up
find $local_backup_path/$HOSTNAME.*.img -mtime +$days_to_keep_locally -type f -delete

@smcalilly
Copy link
Author

add env variables

@smcalilly
Copy link
Author

cd ../backupper/
#key gen
echo "$CLIENT_PUBLIC_KEY" > authorized_keys

cat authorized_keys

hopefully you did this right. gotta be logged into backupper on both machines to do this

@smcalilly
Copy link
Author

mkdir backups
mkdir self
mkdir $REMOTE_BACKUP_HOST

mkdir backups && mkdir backups/self && mkdir backups/ssd

test you can scp
touch hi.md
scp -P 2164 hi.md backupper@walter:~/backups/ssd

see that in the remote target

@smcalilly
Copy link
Author

@smcalilly
Copy link
Author

df -h .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment