poor-man-backup/poor-man-backup.sh

297 lines
10 KiB
Bash
Executable File

#!/bin/sh
# A poor man backup
# version 0.3
# A simple wrapper script to create a safe and redundant backup.
# Requires: bash, GnuPG, duplicity, rdiff-backup, ssh, figlet
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# The script attempts 3 differents backup:
# To a SD card via duplicity, encrypted with gnupg. It prevents ransom-ware.
# To a remote Pc via duplicity and ssh, encrypted with gnupg. It prevents lost or damage.
# To a remote Pc with encrypted disk via rdiff-backup. Plain mirror for easy recovering.
#
# +-------------------------------+ +-------------+
# | HOME | | SD CARD |
# | |---> duplicity |
# | | | encrypted |
# +-------------------------------+ +-------------+
# | |
# | |
# +--v--------------+ +------v-----------+
# | REMOTE SSH PC1 | | REMOTE SSH PC2 |
# | duplicity | | rdiff-backup |
# | encrypted | | plain mirror |
# +-----------------+ +------------------+
#
# Optional: copies selected config files in $HOME/backups
#
# It is recommended to do a full backup every now and then, therefore
# the script ask for a full backup every 6 months, and ask to delete
# the old full backup every 7 months. Make sure you have enough space
# for 2 full backups in your destination drive. A full backup takes
# time, you better allow it before going to sleep
#
# Important: please remember to backup your gpg-private key separately
# because you will need it to access the encrypted backup.
#
# The script verifies that gpg-agent is running and mount the SD card,
# it is supposed to be well-commented and intentionally is all manual.
# In case you wants to automatize you need ssh and gpg passwordless and
# add the script to cron.
#
# my poor's man backup: hope you find this useful
# To make it yours you need to customize your paths and your shouts
# in the section below: VARIABLES
# Good luck and may you never need to recover.
#
# Comments? Kudos? Curses? Advices? Thank you!
# dan [at] autistici.org
###############
# Invariables #
###############
# We don't need to change anything here
USER=`whoami`
DATE=`date -I` ## only date w/o hours and minutes
HOST=`hostname`
#############
# Variables #
#############
# Here you Define your variables:
# BUINT is where you want to save a copy of your modified config files.
# BUEXT is your removable memory, perhaps an unmounted SD card.
# BUREM1 is the first remote file system, non-encrypted. Thus backup goes encrypted there.
# BUREM2 is the second remote file system, encrypted. Thus backup goes un-encrypted there.
# BUSSH is the ssh-key
# BUNO is the exclude list txt file
# BUGPG is the encrypt and sign-key key-id
BUINT=$HOME/backups
BUEXT=/mnt/sd
BUREM1=zora ## the name of a remote FS as defined in ~/.ssh/config
BUREM2=zelda ## another
BUSSH=$HOME/.ssh/id_rsa
BUNO=$HOME/.exclude
BUGPG=Key-ID
###########################################################
# There should be no need to change anything from now on, #
# but all that has been written with the goal to be read #
###########################################################
#########################
# Because it looks good #
#########################
figlet "backup time"
echo " "
date
echo " "
########################################
# Optional: local backup system config #
########################################
#########################################################
# I want to copy those modified config files in my HOME #
# before to backup the whole $HOME #
# Here you can name as many as you want. #
#########################################################
echo "Salvate i quadri! Copio quei file di sistema"
echo "Save the paintings! Let's save a copy of those system files"
# Personally i like the italian echo version and cannot live without
cat /etc/fstab > $BUINT/$HOST-etc-fstab ;
cat /etc/hosts > $BUINT/$HOST-etc-hosts ;
cat /etc/hosts.deny > $BUINT/$HOST-etc-hosts-deny ;
cat /etc/hosts.allow > $BUINT/$HOST-etc-hosts-allow ;
cat /etc/motd > $BUINT/$HOST-etc-motd ;
crontab -l > $BUINT/$HOST-$USER-crontab
# Keep track of the installed software
echo "List installed software and copying sources.list"
dpkg --get-selections | grep -vi kernel > $BUINT/$HOST-dpkg-sw-list.conf ;
cat /etc/apt/sources.list > $BUINT/$HOST-etc-apt-sources.list ;
cat /etc/apt/preferences.d/preferences > $BUINT/$HOST-etc-apt-preferences.d-preferences ;
ls -lhp /usr/local/bin > $BUINT/$HOST-sw-in-usr-local-bin.txt ;
echo " "
#################################
# Check if gpg-agent is running #
#################################
echo " "
echo "calling gpg-agent:"
gpg-agent
if ! gpg-agent 2>/dev/null; then
echo 'Per fare un backup, ci vuole un gpg-agent'
echo "You need a gpg-agent running"
echo "Aborting execution - Exit"
exit 5
else
echo " "
fi
########################################################################################
# You can launch gpg-agent with: #
# eval $(gpg-agent --daemon) #
# but it should really start at login #
# On my box i have in ~/config/openbox/autostart #
# gpg-agent --daemon --enable-ssh-support --write-env-file "${HOME}/.gpg-agent-info" & #
########################################################################################
#######################################################################################
# To be safe from ransonware, I keep my removable backup offline. #
# the if-statement check the exit code of grep, which indicates if there was a match. #
# I don't want the output displayed, so i redirect it to /dev/null #
#######################################################################################
#####################
# Mount the SD card #
#####################
echo "Calling $BUEXT:"
if mount | grep $BUEXT > /dev/null; then
echo "$BUEXT is already mounted and available"
else
echo 'Per fare un tavolo, ci vuole un legno..'
echo 'Per fare un backup, ci vuole una memoria'
echo 'We need a memory.'
echo "Mounting $BUEXT:"
sudo mount $BUEXT
sleep 2
fi
# Verify that external storage is mounted
if mount | grep $BUEXT > /dev/null; then
echo " "
else
echo "$BUEXT DID NOT MOUNT"
echo "Aborting execution - Exit"
echo " "
exit 5
fi
#######################################
# Encrypted backup on external memory #
#######################################
echo "Nessun impedimento. Questo backup s'ha da fare."
echo "Backup on $BUEXT via duplicity and gpg (y/n)"
read input
if [ "$input" = "y" ]; then
echo " "
echo "Go go go with first backup. A full one every 6 months"
echo "Vai col primo backup"
echo " "
duplicity --encrypt-sign-key $BUGPG --use-agent --full-if-older-than 6M --exclude-filelist $BUNO $HOME/ file:///$BUEXT/backups
sleep 1
echo "Let me erase backups older than 7 month from $BUEXT"
echo " "
duplicity remove-all-but-n-full 2 --encrypt-sign-key $BUGPG --force file:///$BUEXT/backups
echo " "
else
echo "(N)o backup on $BUEXT"
echo " "
fi
###########################
# Umount external storage #
###########################
echo "Umount $BUEXT (y/n)"
read input
if [ "$input" = "y" ]; then
sudo umount $BUEXT
sleep 2
else
echo "(N)o, exit and not umounting $BUEXT"
exit 5
fi
################################################
# Verify that the external memory got umounted #
################################################
if mount | grep $BUEXT > /dev/null; then
echo "$BUEXT DID NOT UMOUNT"
echo " "
exit 5
else
echo "(Y) Umounted $BUEXT"
fi
#################################
# Check if ssh-agent is running #
#################################
if [ -z "$SSH_AUTH_SOCK" ] ; then
echo "calling ssh-agent"
eval `ssh-agent` ; ssh-add $BUSSH
else
echo " "
fi
####################################################
# Backup with duplicity and GPG on BUREM1 via ssh #
####################################################
echo "Signora Ceccarelli ne facciamo un'altra?"
echo "Backup on $BUREM1 via ssh, duplicity and gpg (y/n)"
read input
if [ "$input" = "y" ]; then
echo " "
echo "Go go go with second backup. A full one every 6 months"
echo "Vai col secondo backup"
echo " "
duplicity --encrypt-sign-key $BUGPG --use-agent --full-if-older-than 6M --exclude-filelist $BUNO $HOME/ sftp://$USER@$BUREM1//home/$USER/backups
sleep 1
echo "Let me erase backups older than 7 month from $BUREM1"
echo " "
duplicity remove-all-but-n-full 1 --encrypt-sign-key $BUGPG --force sftp://$USER@$BUREM1//home/$USER/backups
else
echo "(N)o backup su $BUREM1"
echo " "
fi
########################################################################
# Backup unencrypted with rdiff-backup on BUREM2 (encrypted hard disk) #
########################################################################
echo " "
echo "Signora Ceccarelli!"
echo "Andiamo su non faccia la manfrina, ne facciamo un'altra."
echo "Backup plain mirror on $BUREM2 with rdiff-backup via ssh (y/n)"
read input
if [ "$input" = "y" ]; then
echo " "
echo "Go go go with third backup"
echo "Vai col terzo backup"
rdiff-backup --exclude-filelist $BUNO $HOME/ $BUREM2::/home/$USER/backup/$USER
echo " "
echo "Let me erase backups older than 1 year from $BUREM2"
rdiff-backup --remove-older-than 52W $BUREM2::/home/$USER/backup/$USER
echo " "
echo "So Long, and Thanks for All the Fish"
echo " "
else
echo "(N)o backup on $BUREM2"
echo " "
exit 5
fi