#!/bin/bash #/###################################################################\ #| Make backup of: | #| -Web Pages (/var/www) | #| -SQL Databases (MySQL or MariaDB) | #| -HTTP Server Configuration (nginx) | #| -Let's Encrypt Certificates | #| -Home Directory (/home) | #| -GOGS Git Repository | #| -Mail Mailboxes (/var/mail) | #| -PostFix MTA Configuration (SMTP mail server) | #| -Dovecot MDA Configuration (POP3/IMAP server) | #| -OpenDKIM Configuration (Anti email Spoofing) | #| -SPF Configuration (Anti email Spoofing) | #| -OpenDMARC Configuration (Anti email Spoofing) | #| -Amavis Configuration (Antivirus) | #| -SPAM Assassin (AntiSPAM) | #| Compressed with: | #| -Gzip | #| -Bzip2 | #| -XZ | #| -7zip | #| and encrypted (or not). | #| | #| USAGE: backup-server [options] -z|-j|-J|-7 backupdir | #| HELP: backup-server -h | #| | #| Guzmán Castanedo (guzman@castanedo.es) | #| Version 2.1 (May 2018) | #| Licence: GPL v3.0 -> https://www.gnu.org/licenses/gpl-3.0.en.html | #\###################################################################/ function usage { printf "%s Version 2.1\n" $(basename $0) printf "Usage: %s [options]... -z|-j|-J|-7 [backupdir]\n" $(basename $0) printf "Make a encrypted backup of a server compressed with: \n" printf "\t·Gzip (tar.gz or tar.gz.gpg)\n" printf "\t·Bzip2 (tar.bz2 or tar.gz.gpg)\n" printf "\t·XZ (tar.xz or tar.xz.gpg)\n" printf "\t·7Z (7z)\n" printf "\n" printf "Backup Directory:\n" printf "\tbackupdir: argument to set to directory to save the backup\n" printf "\t\tDefault: %s\n" $backupDir printf "Backup Options:\n" printf "\t-p, --prefix name: prefix for the name of the backup\n" printf "\t\tDefault: backup-'hostname'(%s)\n" $backupPrefix printf "\t--postfix name: postfix for the name of the backup.\n" printf "\t\tTo unset default postfix: --postfix \"\"\n" printf "\t\tDefault: prefix-yyyy-mm-dd(date)-XXXXXX(random)\n" printf "\t--no-remove: no remove old files\n" printf "\t\tDefault: false\n" printf "\t--remove-days number: set number of days to considere a backup old\n" printf "\t\tDefault: %s\n" $deleteDays printf "\t-u, --user uid: name of the user owner of the backup\n" printf "\t\tDefault: %s\n" $user printf "\t-g, --group gid: name of the group owner of the backup\n" printf "\t\tDefault: %s\n" $group printf "\t--permision-mask number: octal mask to set accesss permision of the backup\n" printf "\t\tDefault: %s\n" $permisionMask printf "\n" printf "Compression Options:\n" printf "\t-z, --gzip: compress using gzip (tar.gz or tar.gz.gpg)\n" printf "\t-j, --bzip2: compress using bzip2 (tar.bz2 or tar.bz2.gpg)\n" printf "\t-J, --xz: compress using xz (tar.xz or tar.xz.gpg)\n" printf "\t-7, --7zip: compress using 7z (7z)\n" printf "\n" printf "Encryption Options:\n" printf "\t-k, --key-id ID: set gpg2 public key-id used for encryption\n" printf "\t\tUse with Gzip, Bzip2 or XZ compression\n" printf "\t\tDefault: %s\n" $keyID printf "\t--no-encryption: disable the encryption of the backup\n" printf "\t\tDefault: %s\n" $noEncryption printf "\t--7z-password password: set password (ONLY for 7z) (INSECURE)\n" printf "\t\tDefault: %s\n" $pass7z printf "\n" printf "Web Options:\n" printf "\t--web-dir dir: set web pages directory to backup\n" printf "\t\tDefault: %s\n" $webDir printf "\t--no-web: disable backup of web pages\n" printf "\t\tDefault: %s\n" $noWeb printf "\n" printf "SQL Options:\n" printf "\t--no-sql: disable MySQL/MariaDB backup\n" printf "\t\tDefault: %s\n" $noSql printf "\t--sql-user username: set MySQL/MariaDB username\n" printf "\t\tDefault: %s\n" $mysqluser printf "\t--sql-password password: set MySQL/MariaDB password (INSECURE)\n" printf "\t\tDefault: %s\n" $mysqlpass printf "\n" printf "Nginx Options:\n" printf "\t--nginx-dir dir: set nginx configuration directory to backup\n" printf "\t\tDefault: %s\n" $nginxDir printf "\t--no-nginx: disable Nginx backup\n" printf "\t\tDefault: %s\n" $noNginx printf "\n" printf "Let's Encrypt Options:\n" printf "\t--letsencrypt-dir dir: set Let's Encrypt configuration directory to backup\n" printf "\t\tDefault: %s\n" $letsencryptDir printf "\t--no-letsencrypt: disable Let's Encrypt backup\n" printf "\t\tDefault: %s\n" $noLetsencrypt printf "\n" printf "Mail Options:\n" printf "\t--mail-dir dir: set Mailboxes directory to backup\n" printf "\t\tDefault: %s\n" $mailDir printf "\t--no-mail: disable mailboxes backup\n" printf "\t\tDefault: %s\n" $noMail printf "\n" printf "Home Options:\n" printf "\t--home-dir dir: set home directories to backup\n" printf "\t\tDefault: %s\n" $homeDir printf "\t--no-home: disable home directory backup\n" printf "\t\tDefault: %s\n" $noHome printf "\n" printf "GOGS Options:\n" printf "\t--gogs-dir dir: set GOGS Git Repository to backup\n" printf "\t\tDefault: %s\n" $gogsDir printf "\t--no-gogs: disable gogs backup\n" printf "\t\tDefault: %s\n" $noGogs printf "\n" printf "Postfix Options:\n" printf "\t--postfix-dir dir: set Postfix configuration directory to backup\n" printf "\t\tDefault: %s\n" $postfixDir printf "\t--no-postfix: disable Postfix backup\n" printf "\t\tDefault: %s\n" $noPostfix printf "\n" printf "Dovecot Options:\n" printf "\t--dovecot-dir dir: set Dovecot configuration directory to backup\n" printf "\t\tDefault: %s\n" $dovecotDir printf "\t--no-dovecot: disable Dovecot backup\n" printf "\t\tDefault: %s\n" $noDovecot printf "\n" printf "OpenDKIM Options:\n" printf "\t--opendkim-conf file: set OpenDKIM configuration file to backup\n" printf "\t\tDefault: %s\n" $openDKIMConf printf "\t--opendkim-default file: set OpenDKIM socket configuration file to backup\n" printf "\t\tDefault: %s\n" $openDKIMDefault printf "\t--opendkim-keys dir: set OpenDKIM keys dir to backup\n" printf "\t\tDefault: %s\n" $openDKIMKeys printf "\t--no-opendkim: disable OpenDKIM backup\n" printf "\t\tDefault: %s\n" $noOpenDKIM printf "\n" printf "SPF Options:\n" printf "\t--spf-dir dir: set SPF configuration directory to backup\n" printf "\t\tDefault: %s\n" $spfDir printf "\t--no-spf: disable SPF backup\n" printf "\t\tDefault: %s\n" $noSPF printf "\n" printf "OpenDMARC Options:\n" printf "\t--opendmarc-conf file: set OpenDMARC configuration file to backup\n" printf "\t\tDefault: %s\n" $openDMARCConf printf "\t--opendmarc-default file: set OpenDMARC socket configuration file to backup\n" printf "\t\tDefault: %s\n" $openDMARCDefault printf "\t--no-opendmarc: disable OpenDMARC backup\n" printf "\t\tDefault: %s\n" $noOpenDMARC printf "\n" printf "Amavis Options:\n" printf "\t--amavis-dir dir: set Amavis configuration directory to backup\n" printf "\t\tDefault: %s\n" $amavisDir printf "\t--no-amavis: disable Amavis backup\n" printf "\t\tDefault: %s\n" $noAmavis printf "\n" printf "SPAM Assassin Options:\n" printf "\t--spamassassin-dir dir: set SPAM Assassin configuration directory to backup\n" printf "\t\tDefault: %s\n" $spamAssassinDir printf "\t--no-spamassassin: disable SPAM Assassin backup\n" printf "\t\tDefault: %s\n" $noSpamAssassin printf "\n" printf "Other Options:\n" printf "\t--no-sha512: not calculate SHA512 hash (to check integrity)\n" printf "\t-h, --help: shows this message and exit\n" printf "\n" printf "Examples:\n" printf "\t·%s --xz -k ABCDEFG -p backup-example.com --no-sql /var/backup\n" $(basename $0) printf "\t\tMake a backup in \"/var/backup\" compressed with XZ and encrypted with GPG2\n" printf "\t\tPublic Key (\"backup-example.com-2018-03-19-a1b2c3.tar.xz.gpg\")\n" printf "\t\tDisable SQL backup\n" printf "\t·%s -7 --7z-password 7zpass --sql-user root --sql-password toor /var/www/backup\n" $(basename $0) printf "\t\tMake a backup in \"/var/www/backup\" compressed with 7Zip and encrypted\n" printf "\t\t(\"backup-'hostname'-2018-03-19-abcdef.7z\")\n" printf "\t·%s -z --no-encryption --no-sql /var/backup\n" $(basename $0) printf "\t\tMake a backup in \"/var/backup\" compressed with GZip and not encrypted\n" printf "\t\t(\"backup-'hostname'-2018-03-19-qwerty.tar.gz\")\n" } function makep7zip { #Destination file encrypt7z="" if [ ! -z $pass7z ];then encrypt7z="-p$pass7z -mhe" fi if [ $noEncryption = true ];then encrypt7z="" fi printf "Backup File:\t%s\n" $backupOutput #Copy webpages code (except backup and main/public) if [ $noWeb = false ];then printf "Compressing:\t%s\n" $webDir tempfile=$(mktemp -t exclude-XXX) echo "www/backup" > $tempfile echo "www/main/public" >> $tempfile 7z a -t7z -mx=9 $encrypt7z $backupOutput $webDir -x@$tempfile > /dev/null if [ $? != 0 ];then printf "WARNING:\tError copying web pages (Continue).\n" fi rm $tempfile fi #Copy MySQL databases (mysqldump) if [ $noSql = false ]; then list=$(mysql -u $mysqluser -p$mysqlpass -e "show DATABASES;") #Parse databases expect information_schema & performance_schema for database in $list; do valid=true for excep in Database information_schema performance_schema; do if [ $database = $excep ]; then valid=false break fi done if [ $valid = true ]; then printf "Compressing MySQL database:\t%s\n" $database.sql mysqldump -u $mysqluser -p$mysqlpass $database | 7z a -t7z -mx=9 $encrypt7z $backupOutput -simysql/$database.sql > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError compressing database (%s) (Continue).\n" $database fi fi done fi #Copy nginx configuration (sites-available) if [ $noNginx = false ];then printf "Compressing:\t%s\n" $nginxDir 7z a -t7z -mx=9 $encrypt7z $backupOutput $nginxDir > /dev/null if [ $? != 0 ];then printf "WARNING:\tError copying nginx configuration (Continue)\n" fi fi #Copy Email (this could be heavy in the future) if [ $noMail = false ];then printf "Compressing:\t%s\n" $mailDir 7z a -t7z -mx=9 $encrypt7z $backupOutput $mailDir > /dev/null #tar -c -zf - $mailDir | 7z a -t7z -mx=9 -p$pass7z -mhe $backupOutput -simail.tar.gz > /dev/null if [ $? != 0 ];then printf "WARNING:\tError copying mailboxes (Continue)\n" fi fi #Copy Certificates (LetsEncrypt) if [ $noLetsencrypt = false ];then printf "Compressing:\t%s\n" $letsencryptDir 7z a -t7z -mx=9 $encrypt7z $backupOutput $letsencryptDir > /dev/null if [ $? != 0 ];then printf "WARNING:\tError copying Let's Encrypt certificates (Continue)\n" fi fi #Copy /home if [ $noHome = false ];then printf "Compressing:\t%s\n" $homeDir 7z a -t7z -mx=9 $encrypt7z $backupOutput $homeDir > /dev/null if [ $? != 0 ];then printf "WARNING:\tError copying home dir (Continue)\n" fi fi #Copy GOGS if [ $noGogs = false ];then printf "Compressing:\t%s\n" $gogsDir 7z a -t7z -mx=9 $encrypt7z $backupOutput $gogsDir > /dev/null if [ $? != 0 ];then printf "WARNING:\tError copying GOGS Repository (Continue)\n" fi fi #Copy Postfix if [ $noPostfix = false ] && [ -d $postfixDir ];then printf "Compressing:\t%s\n" $postfixDir 7z a -t7z -mx=9 $encrypt7z $backupOutput $postfixDir > /dev/null if [ $? != 0 ];then printf "WARNING:\tError copying Postfix configuration (Continue)\n" fi fi #Copy Dovecot if [ $noDovecot = false ];then printf "Compressing:\t%s\n" $dovecotDir 7z a -t7z -mx=9 $encrypt7z $backupOutput $dovecotDir > /dev/null if [ $? != 0 ];then printf "WARNING:\tError copying Dovecot configuration (Continue)\n" fi fi #Copy OpenDKIM if [ $noOpenDKIM = false ];then if [ -f $openDKIMConf ];then printf "Compressing:\t%s\n" $openDKIMConf 7z a -t7z -mx=9 $encrypt7z $backupOutput $openDKIMConf > /dev/null if [ $? != 0 ];then printf "WARNING:\tError copying OpenDKIM configuration (Continue)\n" fi else printf "WARNING:\tFile %s not exist\n" $openDKIMConf fi if [ -f $openDKIMDefault ];then printf "Compressing:\t%s\n" $openDKIMDefault 7z a -t7z -mx=9 $encrypt7z $backupOutput $openDKIMDefault > /dev/null if [ $? != 0 ];then printf "WARNING:\tError copying OpenDKIM sockets configuration (Continue)\n" fi else printf "WARNING:\tFile %s not exist\n" $openDKIMDefault fi if [ -d $openDKIMKeys ];then printf "Compressing:\t%s\n" $openDKIMKeys 7z a -t7z -mx=9 $encrypt7z $backupOutput $openDKIMKeys > /dev/null if [ $? != 0 ];then printf "WARNING:\tError copying OpenDKIM keys (Continue)\n" fi else printf "WARNING:\tDir %s not exist\n" $openDKIMKeys fi fi #Copy SPF if [ $noSPF = false ];then printf "Compressing:\t%s\n" $spfDir 7z a -t7z -mx=9 $encrypt7z $backupOutput $spfDir > /dev/null if [ $? != 0 ];then printf "WARNING:\tError copying Postfix configuration (Continue)\n" fi fi #Copy OpenDMARC if [ $noOpenDMARC = false ];then if [ -f $openDMARCConf ];then printf "Compressing:\t%s\n" $openDMARCConf 7z a -t7z -mx=9 $encrypt7z $backupOutput $openDMARCConf > /dev/null if [ $? != 0 ];then printf "WARNING:\tError copying OpenDMARC configuration (Continue)\n" fi else printf "WARNING:\tFile %s not exist\n" $openDMARCConf fi if [ -f $openDMARCDefault ];then printf "Compressing:\t%s\n" $openDMARCDefault 7z a -t7z -mx=9 $encrypt7z $backupOutput $openDMARCDefault > /dev/null if [ $? != 0 ];then printf "WARNING:\tError copying OpenDMARC sockets configuration (Continue)\n" fi else printf "WARNING:\tFile %s not exist\n" $openDMARCDefault fi fi #Copy Amavis if [ $noAmavis = false ];then printf "Compressing:\t%s\n" $amavisDir 7z a -t7z -mx=9 $encrypt7z $backupOutput $amavisDir > /dev/null if [ $? != 0 ];then printf "WARNING:\tError copying Amavis configuration (Continue)\n" fi fi #Copy SPAMAssassin if [ $noSpamAssassin = false ];then printf "Compressing:\t%s\n" $spamAssassinDir 7z a -t7z -mx=9 $encrypt7z $backupOutput $spamAssassinDir > /dev/null if [ $? != 0 ];then printf "WARNING:\tError copying SPAM Assasin configuration (Continue)\n" fi fi } function makeTar { #Destination file printf "Backup File:\t%s\n" $backupOutput #Copy webpages code (except backup and main/public) if [ $noWeb = false ];then printf "Adding:\t%s\n" $webDir tar -rf $tempOutput --exclude=var/www/backup --exclude=var/www/main/public $webDir > /dev/null 2>&1 if [ $? != 0 ]; then printf "WARNING:\tError copying web pages (Continue).\n" fi fi #Copy MySQL databases (mysqldump) if [ $noSql = false ]; then list=$(mysql -u $mysqluser -p$mysqlpass -e "show DATABASES;" 2> /dev/null) mkdir /tmp/mysql #Parse databases expect information_schema & performance_schema for database in $list; do valid=true for excep in Database information_schema performance_schema; do if [ $database = $excep ]; then valid=false break fi done if [ $valid = true ]; then printf "Adding MySQL database:\t%s\n" $database.sql mysqldump -u $mysqluser -p$mysqlpass $database > /tmp/mysql/$database.sql 2> /dev/null if [ $? != 0 ];then printf "WARNING:\tError extracting database (%s) (Continue).\n" $database continue fi tar -rf $tempOutput -C /tmp mysql/$database.sql > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError adding to tar (%s) (Continue)\n" fi rm /tmp/mysql/$database.sql fi done rm -R /tmp/mysql fi #Copy nginx configuration (sites-available) if [ $noNginx = false ];then printf "Adding:\t%s\n" $nginxDir tar -rf $tempOutput $nginxDir > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError copying nginx configuration (Continue)\n" fi fi #Copy Email (this could be heavy in the future) if [ $noMail = false ];then printf "Adding:\t%s\n" $mailDir tar -rf $tempOutput $mailDir > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError copying mailboxes (Continue)\n" fi fi #Copy Certificates (LetsEncrypt) if [ $noLetsencrypt = false ];then printf "Adding:\t%s\n" $letsencryptDir tar -rf $tempOutput $letsencryptDir > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError copying Let's Encrypt certificates (Continue)\n" fi fi #Copy /home if [ $noHome = false ];then printf "Adding:\t%s\n" $homeDir tar -rf $tempOutput $homeDir > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError copying home dir (Continue)\n" fi fi #Copy GOGS if [ $noGogs = false ];then printf "Adding:\t%s\n" $gogsDir tar -rf $tempOutput $gogsDir > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError copying GOGS Repository (Continue)\n" fi fi #Copy Postfix if [ $noPostfix = false ] && [ -d $postfixDir ];then printf "Adding:\t%s\n" $postfixDir tar -rf $tempOutput $postfixDir > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError copying Postfix configuration (Continue)\n" fi fi #Copy Dovecot if [ $noDovecot = false ];then printf "Adding:\t%s\n" $dovecotDir tar -rf $tempOutput $dovecotDir > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError copying Dovecot configuration (Continue)\n" fi fi #Copy OpenDKIM if [ $noOpenDKIM = false ];then if [ -f $openDKIMConf ];then printf "Adding:\t%s\n" $openDKIMConf tar -rf $tempOutput $openDKIMConf > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError copying OpenDKIM configuration (Continue)\n" fi else printf "WARNING:\tFile %s not exist\n" $openDKIMConf fi if [ -f $openDKIMDefault ];then printf "Adding:\t%s\n" $openDKIMDefault tar -rf $tempOutput $openDKIMDefault > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError copying OpenDKIM sockets configuration (Continue)\n" fi else printf "WARNING:\tFile %s not exist\n" $openDKIMDefault fi if [ -d $openDKIMKeys ];then printf "Adding:\t%s\n" $openDKIMKeys tar -rf $tempOutput $openDKIMKeys > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError copying OpenDKIM keys (Continue)\n" fi else printf "WARNING:\tDir %s not exist\n" $openDKIMKeys fi fi #Copy SPF if [ $noSPF = false ];then printf "Adding:\t%s\n" $spfDir tar -rf $tempOutput $spfDir > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError copying Postfix configuration (Continue)\n" fi fi #Copy OpenDMARC if [ $noOpenDMARC = false ];then if [ -f $openDMARCConf ];then printf "Adding:\t%s\n" $openDMARCConf tar -rf $tempOutput $openDMARCConf > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError copying OpenDMARC configuration (Continue)\n" fi else printf "WARNING:\tFile %s not exist\n" $openDMARCConf fi if [ -f $openDMARCDefault ];then printf "Adding:\t%s\n" $openDMARCDefault tar -rf $tempOutput $openDMARCDefault > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError copying OpenDMARC sockets configuration (Continue)\n" fi else printf "WARNING:\tFile %s not exist\n" $openDMARCDefault fi fi #Copy Amavis if [ $noAmavis = false ];then printf "Adding:\t%s\n" $amavisDir tar -rf $tempOutput $amavisDir > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError copying Amavis configuration (Continue)\n" fi fi #Copy SPAMAssassin if [ $noSpamAssassin = false ];then printf "Adding:\t%s\n" $spamAssassinDir tar -rf $tempOutput $spamAssassinDir > /dev/null 2>&1 if [ $? != 0 ];then printf "WARNING:\tError copying SPAM Assasin configuration (Continue)\n" fi fi } function gzUnencrypted { printf "Compressing (GZIP)..." gzip -9 --stdout $tempOutput > $backupOutput if [ $? != 0 ]; then printf "\nERROR:\tImpossible to compress (%s)\n" $backupOutput$ext exit 1 fi rm $tempOutput printf " done\n" } function gzEncrypted { printf "Compressing (GZIP) and encrypting..." gzip -9 --stdout $tempOutput | gpg2 --no-batch --output $backupOutput --encrypt -r $keyID - if [ $? != 0 ]; then printf "\nERROR:\tImpossible to compress (%s)\n" $backupOutput$ext exit 1 fi rm $tempOutput printf " done\n" } function bz2Unencrypted { printf "Compressing (BZIP2)..." bzip2 -9 --stdout $tempOutput > $backupOutput if [ $? != 0 ]; then printf "\nERROR:\tImpossible to compress (%s)\n" $backupOutput$ext exit 1 fi rm $tempOutput printf " done\n" } function bz2Encrypted { printf "Compressing (BZIP2) and encrypting..." bzip2 -9 --stdout $tempOutput | gpg2 --no-batch --output $backupOutput --encrypt -r $keyID - if [ $? != 0 ]; then printf "\nERROR:\tImpossible to compress (%s)\n" $backupOutput$ext exit 1 fi rm $tempOutput printf " done\n" } function xzUnencrypted { printf "Compressing (XZ)..." xz -9 --stdout $tempOutput > $backupOutput if [ $? != 0 ]; then printf "\nERROR:\tImpossible to compress (%s)\n" $backupOutput$ext exit 1 fi rm $tempOutput printf " done\n" } function xzEncrypted { printf "Compressing (XZ) and encrypting..." xz -9 --stdout $tempOutput | gpg2 --no-batch --output $backupOutput --encrypt -r $keyID - if [ $? != 0 ]; then printf "\nERROR:\tImpossible to compress (%s)\n" $backupOutput$ext exit 1 fi rm $tempOutput printf " done\n" } function makeSHA512 { if [ ! -x $(which sha512sum) ]; then printf "WARNING:\tsha512sum not installed\n" sha512=false fi if [ $sha512 = true ]; then printf "Calculating checksum (SHA512)..." cd $backupDir > /dev/null 2>&1 sha512sum -b $(basename $backupOutput) > $backupOutput.sha512 #Permissions chown $user:$group $backupOutput.sha512 chmod $permisionMask $backupOutput.sha512 cd - > /dev/null 2>&1 printf " done\n" fi } function checkRoutes { if [ ! -d $backupDir ];then printf "ERROR:\tBackup directory don't exist\n" usage exit 1 fi if [ $noWeb = false ] && [ ! -d $webDir ];then printf "WARNING:\t%s don't exist (no backup)\n" $webDir noWeb=true fi if [ $noNginx = false ] && [ ! -d $nginxDir ];then printf "WARNING:\t%s don't exist (no backup)\n" $nginxDir noNginx=true fi if [ $noLetsencrypt = false ] && [ ! -d $letsencryptDir ];then printf "WARNING:\t%s don't exist (no backup)\n" $letsencryptDir noLetsencrypt=true fi if [ $noMail = false ] && [ ! -d $mailDir ];then printf "WARNING:\t%s don't exist (no backup)\n" $mailDir noMail=true fi if [ $noHome = false ] && [ ! -d $homeDir ];then printf "WARNING:\t%s don't exist (no backup)\n" $homeDir noHome=true fi if [ $noGogs = false ] && [ ! -d $gogsDir ];then printf "WARNING:\t%s don't exist (no backup)\n" $gogsDir noGogs=true fi if [ $noPostfix = false ] && [ ! -d $postfixDir ];then printf "WARNING:\t%s don't exist (no backup)\n" $postfixDir noPostfix=true fi if [ $noDovecot = false ] && [ ! -d $dovecotDir ];then printf "WARNING:\t%s don't exist (no backup)\n" $dovecotDir noDovecot=true fi # No noOpenDKIM=true, to make a parcial copy if [ $noOpenDKIM = false ] && [ ! -f $openDKIMConf ];then printf "WARNING:\t%s don't exist (no backup)\n" $openDKIMConf fi if [ $noOpenDKIM = false ] && [ ! -f $openDKIMDefault ];then printf "WARNING:\t%s don't exist (no backup)\n" $openDKIMDefault fi if [ $noOpenDKIM = false ] && [ ! -d $openDKIMKeys ];then printf "WARNING:\t%s don't exist (no backup)\n" $openDKIMKeys fi if [ $noSPF = false ] && [ ! -d $spfDir ];then printf "WARNING:\t%s don't exist (no backup)\n" $spfDir noSpf=true fi # No noOpenDMARC=true, to make a parcial copy if [ $noOpenDMARC = false ] && [ ! -f $openDMARCConf ];then printf "WARNING:\t%s don't exist (no backup)\n" $openDMARCConf fi if [ $noOpenDMARC = false ] && [ ! -f $openDMARCDefault ];then printf "WARNING:\t%s don't exist (no backup)\n" $openDMARCDefault fi if [ $noAmavis = false ] && [ ! -d $amavisDir ];then printf "WARNING:\t%s don't exist (no backup)\n" $amavisDir noAmavis=true fi if [ $noSpamAssassin = false ] && [ ! -d $spamAssassinDir ];then printf "WARNING:\t%s don't exist (no backup)\n" $spamAssassinDir noSpamAssassin=true fi } function checkMethod { if [ $gzipOn = false ] && [ $bzip2On = false ] && [ $xzOn = false ] && [ $p7zipOn = false ];then printf "ERROR:\tCompressing method not set\n" exit 1 fi if [ $noEncryption = false ];then if [ $gzipOn = true ] || [ $bzip2On = true ] || [ $xzOn = true ];then if [ ! -x $(which gpg2) ];then printf "WARNING:\tGPG2 Not Installed: continue without encryption (type \"%s -h\" for help)\n" $(basename $0) noEncryption=true else if [ ! -z $keyID ];then ext=$ext.gpg gpg2 --list-keys $keyID > /dev/null 2>&1 if [ $? != 0 ];then printf "ERROR:\tKeyID %s don't exist in keyring (\"gpg2 --list-keys\" to see all keys)\n" $keyID exit 1 fi else printf "WARNING:\tKeyID (-k keyID) not set: continue without encryption (type \"%s -h\" for help)\n" $(basename $0) noEncryption=true fi fi else if [ -z $pass7z ];then printf "WARNING:\t7Z password (--7z-password) not set: continue without encryption (type \"%s -h\" for help)\n" $(basename $0) noEncryption=true fi fi fi } function checkSqlAuth { if [ $noSql = false ];then if [ ! -x "$(which mysql)" ] || [ ! -x "$(which mysqldump)" ];then printf "WARNING:\tmysql or/and mysqldump Not installed\n" noSql=true fi if [ -z $mysqluser ] || [ -z $mysqlpass ]; then printf "WARNING:\tSQL User/Password not set: continue without SQL backup (type \"%s -h\" for help)\n" $(basename $0) noSql=true fi fi } #Check root startTime=$(date +"%s") if [ $(id -u) -ne 0 ]; then printf "ERROR:\tNeed to be root :O\n" exit 1 fi #Default Data mysqluser="root" mysqlpass="" keyID="" pass7z="" backupDir=/var/www/backup backupPrefix="backup-"$(hostname) backupPostfix=-$(date +"%Y-%m-%d")-$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 6 | head -n 1) deleteDays="15" user="www-data" group="www-data" #Default Routes webDir="/var/www" nginxDir="/etc/nginx" mailDir="/var/mail" letsencryptDir="/etc/letsencrypt" homeDir="/home" gogsDir="/opt/gogs" postfixDir="/etc/postfix" dovecotDir="/etc/dovecot" openDKIMConf="/etc/opendkim.conf" openDKIMDefault="/etc/default/opendkim" openDKIMKeys="/etc/dkimkeys" spfDir="/etc/postfix-policyd-spf-python" openDMARCConf="/etc/opendmarc.conf" openDMARCDefault="/etc/default/opendmarc" amavisDir="/etc/amavis" spamAssassinDir="/etc/spamassassin" #Control Variables noEncryption=false gzipOn=false bzip2On=false xzOn=false p7zipOn=false ext="" permisionMask=640 removeOld=true noWeb=false noSql=false noNginx=false noMail=false noLetsencrypt=false noHome=false noGogs=false noPostfix=false noDovecot=false noOpenDKIM=false noSPF=false noOpenDMARC=false noAmavis=false noSpamAssassin=false sha512=true #Parse args TEMP=$(getopt -q -o zjJ7p:u:g:k:h --longoptions gzip,bzip2,xz,7zip,prefix:,postfix:,no-remove,remove-days:,user:,group:,permision-mask:,key-id:,no-encryption,7z-password:,web-dir:,no-web,no-sql,sql-user:,sql-password:,nginx-dir:,no-nginx,letsencrypt-dir:,no-letsencrypt,mail-dir:,no-mail,home-dir:,no-home,gogs-dir:,no-gogs,postfix-dir:,no-postfix,dovecot-dir:,no-dovecot,opendkim-conf:,opendkim-default:,opendkim-keys:,no-opendkim,spf-dir:,no-spf,opendmarc-conf:,opendmarc-default:,no-opendmarc,amavis-dir:,no-amavis,spamassassin-dir:,no-spamassassin,no-sha512,help --name $(basename $0) -- $@) eval set -- $TEMP unset TEMP while true; do case $1 in -z|--gzip) gzipOn=true ext=".tar.gz" if [ $bzip2On = true ] || [ $xzOn = true ] || [ $p7zipOn = true ];then printf "ERROR:\tOnly choose one compressing method\n" exit 1 fi if [ ! -x $(which gzip) ];then printf "ERROR:\tGzip Not Installed\n" exit 1 fi shift ;; -j|--bzip2) bzip2On=true ext=".tar.bz2" if [ $gzipOn = true ] || [ $xzOn = true ] || [ $p7zipOn = true ];then printf "ERROR:\tOnly choose one compressing method\n" exit 1 fi if [ ! -x $(which bzip2) ];then printf "ERROR:\tBzip2 Not Installed\n" exit 1 fi shift ;; -J|--xz) xzOn=true ext=".tar.xz" if [ $gzipOn = true ] || [ $bzip2On = true ] || [ $p7zipOn = true ];then printf "ERROR:\tOnly choose one compressing method\n" exit 1 fi if [ ! -x $(which xz) ];then printf "ERROR:\tXZ Not Installed\n" exit 1 fi shift ;; -7|--7zip) p7zipOn=true ext=".7z" if [ $gzipOn = true ] || [ $bzip2On = true ] || [ $xzOn = true ];then printf "ERROR:\tOnly choose one compressing method\n" exit 1 fi if [ ! -x $(which 7z) ];then printf "ERROR:\t7Z Not Installed\n" exit 1 fi shift ;; -p|--prefix) backupPrefix=$2 shift 2 ;; --postfix) backupPostfix=$2 shift 2 ;; --no-remove) removeOld=false shift ;; --remove-days) deleteDays=$2 shift 2 ;; -u|--user) grep $2 /etc/passwd > /dev/null 2>&1 if [ $? = 0 ]; then user=$2 else printf "ERROR:\tUser %s don't exist\n" $2 exit 1 fi shift 2 ;; -g|--group) grep $2 /etc/group > /dev/null 2>&1 if [ $? = 0 ];then group=$2 else printf "ERROR:\tGroup %s don't exist\n" $2 exit 1 fi shift 2 ;; --permision-mask) if [ $2 -eq $2 ] 2> /dev/null;then permisionMask=$2 else printf "ERROR:\tPermission has to be a number (%s)\n" $2 exit 1 fi shift 2 ;; -k|--key-id) keyID=$2 shift 2 ;; --no-encryption) noEncryption=true shift ;; --7z-password) pass7z=$2 shift 2 ;; --web-dir) webDir=$2 shift 2 ;; --no-web) noWeb=true shift ;; --no-sql) noSql=true shift ;; --sql-user) mysqluser=$2 shift 2 ;; --sql-password) mysqlpass=$2 shift 2 ;; --nginx-dir) nginxDir=$2 shift 2 ;; --no-nginx) noNginx=true shift ;; --letsencrypt-dir) letsencryptDir=$2 shift 2 ;; --no-letsencrypt) noLetsencrypt=true shift ;; --mail-dir) mailDir=$2 shift 2 ;; --no-mail) noMail=true shift ;; --home-dir) homeDir=$2 shift 2 ;; --no-home) noHome=true shift ;; --gogs-dir) gogsDir=$2 shift 2 ;; --no-gogs) noGogs=true shift ;; --postfix-dir) postfixDir=$2 shift 2 ;; --no-postfix) noPostfix=true shift ;; --dovecot-dir) dovecotDir=$2 shift 2 ;; --no-dovecot) noDovecot=true shift ;; --opendkim-conf) openDKIMConf=$2 shift 2 ;; --opendkim-default) openDKIMDefault=$2 shift 2 ;; --opendkim-keys) openDKIMKeys=$2 shift 2 ;; --no-opendkim) noOpenDKIM=true shift ;; --spf-dir) spfDir=$2 shift 2 ;; --no-spf) noSPF=true shift ;; --opendmarc-conf) openDMARCConf=$2 shift 2 ;; --opendmarc-default) openDMARCDefault=$2 shift 2 ;; --no-opendmarc) noOpenDMARC=true shift ;; --amavis-dir) amavisDir=$2 shift 2 ;; --no-amavis) noAmavis=true shift ;; --spamassassin-dir) spamAssassinDir=$2 shift 2 ;; --no-spamassassin) noSpamAssassin=true shift ;; --no-sha512) sha512=false shift ;; -h|--help) usage exit 0 shift ;; --) #Last One shift break ;; *) #Unspected usage printf "\nERROR:\tInvalid Option (%s)\n" $1 exit 1 ;; esac done if [ ! $# -eq 1 ];then printf "ERROR:\tBackup directory not set\n" usage exit 1 else backupDir=$1 backupName=$backupPrefix$backupPostfix backupOutput=$backupDir/$backupName tempOutput=/tmp/$backupName.tar fi #Check (routes, compression, encryption and SQL auth) checkRoutes checkMethod checkSqlAuth #make tar file or 7z backupOutput=$backupOutput$ext if [ $p7zipOn = true ];then if [ ! -x $(which 7z) ];then printf "ERROR:\tp7zip Not Installed\n" exit 1 fi makep7zip else if [ ! -x $(which tar) ];then printf "ERROR:\tTAR Not Installed\n" exit 1 fi makeTar fi #Compression and encryption (Except 7Zip -> Already done) if [ $gzipOn = true ];then if [ $noEncryption = true ];then gzUnencrypted else gzEncrypted fi elif [ $bzip2On = true ];then if [ $noEncryption = true ];then bz2Unencrypted else bz2Encrypted fi elif [ $xzOn = true ];then if [ $noEncryption = true ];then xzUnencrypted else xzEncrypted fi else if [ $p7zipOn = false ];then printf "ERROR:\tCompression method not set\n" rm $tempOutput exit 1 fi fi #Make SHA512 if [ $sha512 = true ]; then makeSHA512 fi #Permissions chown $user:$group $backupOutput chmod $permisionMask $backupOutput #Remove files older than 15 days if [ $removeOld = true ];then printf "Deletting old backups (+15 days)..." find $backupDir -mindepth 1 -maxdepth 1 -mtime +$deleteDays -type f -iname "$backupPrefix*$ext" -delete if [ $? != 0 ];then printf "\nWARNING:\tImposible to delete old backups (+%s days)\n" $deleteDays fi printf " done\n" fi #End finalTime=$(date +"%s") printf "\n" echo "------------------------------------------------" printf "Backup completed successfully in %s seconds :)\n" $((finalTime-startTime)) echo "------------------------------------------------"