Skip to content

Instantly share code, notes, and snippets.

@SoftCreatR
Last active October 12, 2016 06:06
Show Gist options
  • Save SoftCreatR/6a9bff5da2d5c8413bf2 to your computer and use it in GitHub Desktop.
Save SoftCreatR/6a9bff5da2d5c8413bf2 to your computer and use it in GitHub Desktop.
Advanved Shell Backup - Copyright (c) 2015 by Sascha "SoftCreatR" Greuel - https://www.softcreatr.de - Licensed under CC-BY-SA
#!/bin/bash
#############################################################
# #
# Advanved Shell Backup #
# Copyright (c) 2015 by Sascha "SoftCreatR" Greuel #
# License: http://creativecommons.org/licenses/by-sa/4.0/ #
# Website: https://www.softcreatr.de #
# #
# Authors: Sascha Greuel, Florian Gail, Some others #
# #
#############################################################
##
# Backup main directory (will be created, if it doesn't exist)
##
BACKUPROOT="/root/backup"
##
# Web-Root
##
WEBROOT="/var/www"
##
# Backup directory for database backups (will be created, if it doesn't exist)
##
BACKUPROOTDB="$BACKUPROOT/db"
##
# Backup directory for web data backups (will be created, if it doesn't exist)
##
BACKUPROOTFTP="$BACKUPROOT/data"
##
# Password file (will be created, if it doesn't exist)
##
PASSWDFILE="/root/backup_pass"
##
# Database user
##
DBUSER="root"
##
# Database password
##
DBPASS="5up3r53cr37"
##
# Defaults file (alternatively)
##
DEFAULTSFILE="/etc/mysql/debian.cnf"
##
# Date format for backup subdirectories
##
TODAY=$(date +"%Y-%m-%d")
### DON'T CHANGE ANYTHING BELOW UNLESS YOU KNOW, WHAT YOU ARE DOING ###
START=$(date +%s)
BACKUPDIRDB="$BACKUPROOTDB/$TODAY"
BACKUPDIRFTP="$BACKUPROOTFTP/$TODAY"
VERBOSE=0
# Output (if enabled)
if [ "$1" = "--verbose" ]; then
VERBOSE=1
fi
function println {
if [ "$VERBOSE" -ne 0 ]; then
echo -e $1
fi
}
function backupSize {
if [ "$VERBOSE" -ne 0 ]; then
CHECK=`du -cs $BACKUPDIRDB $BACKUPDIRFTP`
regex="([0-9]+)\s*total"
if [[ $CHECK =~ $regex ]]; then
SIZE=`expr ${BASH_REMATCH[1]} / 1024`
println "Total backup size is roughly $SIZE Megabyte.";
fi
fi
}
# Detect compression binary and most performat compression ratio
if [ "$(type -t pigz)" = "file" ]; then
println "Using pigz for compression"
if [ "$(grep -c ^processor /proc/cpuinfo)" -ge 3 ]; then
println "Found 3 or more cores, using 9 as compression ratio"
COMPRESSCMD="pigz -9"
else
println "Found less than 3 cores, using 3 as compression ratio"
COMPRESSCMD="pigz -3"
fi
else
println "Using gzip for compression"
COMPRESSCMD="gzip -3"
fi
# Create password file, if it doesn't exist
if [ ! -f $PASSWDFILE ]; then
println "Creating password file $PASSWDFILE"
openssl rand -base64 32 -out $PASSWDFILE
fi
# Create backup directories, if they don't exist
if [ ! -d $BACKUPDIRDB ]; then
println "Creating backup directory $BACKUPDIRDB"
mkdir -p $BACKUPDIRDB
fi
if [ ! -d $BACKUPDIRFTP ]; then
println "Creating backup directory $BACKUPDIRFTP"
mkdir -p $BACKUPDIRFTP
fi
##
# Database backup
##
if [ ! -z "$DEFAULTSFILE" ] && [ -f $DEFAULTSFILE ]; then
println "\nRetrieving a list of existing databases, using defaults file $DEFAULTSFILE"
DATABASES=`mysql --defaults-file=$DEFAULTSFILE -Bse 'show databases'`
else
println "\nRetrieving a list of existing databases, using given database credentials"
DATABASES=`mysql -u $DBUSER -p$DBPASS -Bse 'show databases'`
fi
for DB in $DATABASES; do
println "\n"
# Exclude information_schema, performance_schema and mysql from backup
if [ "$DB" = "information_schema" -o "$DB" = "performance_schema" -o "$DB" = "mysql" ]; then
println "Skipping database $DB"
continue
fi
# Back up current database
SQLFILE="$BACKUPDIRDB/$DB.gz"
println "Dumping and compressing $DB to $SQLFILE"
if [ ! -z "$DEFAULTSFILE" ] && [ -f $DEFAULTSFILE ]; then
mysqldump --defaults-file=$DEFAULTSFILE --single-transaction "$DB" | $COMPRESSCMD > $SQLFILE
else
mysqldump -u "$DBUSER" -p"$DBPASS" --single-transaction "$DB" | $COMPRESSCMD > $SQLFILE
fi
# Encrypt backup
ENCFILE="$SQLFILE.enc"
println "Encrypting $SQLFILE"
openssl enc -aes-256-cbc -in $SQLFILE -out $ENCFILE -salt -pass file:$PASSWDFILE
# Delete unencrypted backup file
println "Deleting unencrypted backup file $SQLFILE"
rm $SQLFILE
done
##
# Data backup
##
cd $WEBROOT
for DIR in $WEBROOT/*; do
println "\n"
# Exclude inaccessible directories from backup
if [ ! "$(ls -A $DIR)" ]; then
println "Skipping directory $DIR"
continue
fi
APATH=${DIR%*/}
RPATH=${APATH##*/}
# Back up current directory
FILENAME="$BACKUPDIRFTP/$RPATH.tgz"
println "Dumping and encrypting directory $PWD/$RPATH to $FILENAME"
tar cf - $RPATH | $COMPRESSCMD > $FILENAME
# Encrypt backup
ENCFILE="$FILENAME.enc"
println "Encrypting $FILENAME"
openssl enc -aes-256-cbc -in $FILENAME -out $ENCFILE -salt -pass file:$PASSWDFILE
# Delete unencrypted backup file
println "Deleting unencrypted backup file $FILENAME"
rm $FILENAME
done
END=$(date +%s)
echo -e "\nThat's it! The backup has been successfully finished after $((END-START)) seconds.";
backupSize
exit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment