I wrote a fairly simple bash script that creates encrypted backups of any given file or directory. The script will delete old backup sets and should be run daily as a cronjob. It requires that rsync be installed.
Please feel free to use, modify and share the code. I am also looking forward to suggestions on how to improve the script.
Here it is:
Code: Select all
#!/bin/bash
###########################################
### ###
### (c) 2016 by Matthias Ewering ###
### ###
### matthias.ewering@posteo.de ###
### ###
### !! No warranty whatsoever !! ###
### ###
###########################################
source=/path/to/source #The element to be backed up
daily=/path/to/backup/daily #The directory that will contain the daily backup files
weekly=/path/to/backup/weekly #The directory that will contain the weekly backup files
monthly=/path/to/backup/monthly #The directory that will contain the monthly backup files
main=/path/to/backup #The main backup directory for all backup cycles
mirror1=/path/to/backup_mirror1 #The first mirror of the main backup directory
mirror2=/path/to/backup_mirror2 #The second mirror of the main backup directory
#mirrorn=/foo/bar #The n^th mirror of the main backup directory
tar -czPf ./$(date +"%Y-%m-%d_%H-%M")_backup.tar.gz "$source" #Create a compressed tarball with the contents to be backed up
gpg --symmetric --cipher-algo aes256 --passphrase secret -o ./$(date +"%Y-%m-%d_%H-%M")_backup.tar.gz.gpg ./*_backup.* #Encrypt the tarball. Remember to replace "secret" with A CUSTOM, SECURE PASSPHRASE!
mv ./*.gpg "$daily" #Move the encrypted backup file to the main daily backup directory
rm ./*_backup.* #Delete the unencrypted tarball
find "$daily" -type f | sort -rd | sed -e '1,7d' | xargs -d '\n' rm -- #Delete any file from the main daily backup directory with the 8th oldest timestamp or older
if [ $(date +"%u") = "7" ]
then find "$daily" -type f | sort -d | sed -e '1,6d' | xargs cp -t "$weekly"
#On a Sunday, copy the latest daily backup file to the weekly backup directory,...
find "$weekly" -type f | sort -rd | sed -e '1,5d' | xargs -d '\n' rm -- #...then delete any file from the weekly backup directory with the 6th oldest...
#...timestamp or older
fi
if [ $(find "$daily" -type f | sort -rd | awk -F '/' '{print $NF}' | cut -c1-4 | head -2 | tail -1) -lt $(date +"%Y") ]
#When a new year has begun, create an archive directory for...
then mkdir "$main"/$(($(date +"%Y") - 1)) #...the old year and move the monthly files to that archive directory
mv "$monthly"/*.gpg "$main"/$(($(date +"%Y") - 1))
fi
if [ $(date +"%d") = "01" ]
#On the first of a month, copy the latest daily backup file to the monthly backup directory
then find "$daily" -type f | sort -d | sed -e '1,6d' | xargs cp -t "$monthly"
fi
rsync -a --delete "$main" "$mirror1" #Synchronize the first mirror directory with the main backup directory
rsync -a --delete "$main" "$mirror2" #Synchronize the second mirror directory with the main backup directory
#rsync -a --delete "$main" "$mirrorn" #Synchronize the n^th mirror directory with the main backup directory
exit 0
edit: corrected a sorting error.