fist commit
This commit is contained in:
commit
cbae1a5ddd
53
README.md
Executable file
53
README.md
Executable file
|
@ -0,0 +1,53 @@
|
||||||
|
# A poor man backup
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
A simple wrapper script to create a safe and redundant backup
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
Requires: bash, GnuPG, duplicity, rdiff-backup, ssh, figlet
|
||||||
|
|
||||||
|
##
|
||||||
|
|
||||||
|
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 you 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 run 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
|
||||||
|
to setup 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
|
||||||
|
Good luck and may you never need to recover.
|
||||||
|
|
||||||
|
Comments? Kudos? Vaffa? Advices? Thank you!
|
||||||
|
dan [at] autistici.org
|
||||||
|
|
296
poor-man-backup.sh
Executable file
296
poor-man-backup.sh
Executable file
|
@ -0,0 +1,296 @@
|
||||||
|
#!/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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user