ulfben icon

backup.sh (rotating archives, encrypted)

ulfben | PRO | 01/09/18 09:35:41 PM UTC | 0 ⭐ | 1182 👁️ | Never ⏰ | []
Bash |

4.58 KB

|

None

|

0 👍

/

0 👎

#!/bin/bash
# backup.sh - a basic backup script with grandfather-father-son rotation:
#  - The rotation will do a daily backup Sunday through Friday.
#  - On Saturday a weekly backup is done giving you four weekly backups a month.
#  - The monthly backup is done on the first of the month, rotating two monthly backups (odd/even)
#
# The script was inspired by the Ubuntu Server Guide https://help.ubuntu.com/lts/serverguide/backups.html
#
# backup.sh will archive using tar + gzip (multithreaded) and then encrypt using 7z (AES256, no compression)
# This is MUCH faster than it is to let 7z compress-&-encrypt in a single step - even at x=0.
# Plus 7z is unfit for backup duty on Linux (see the man-page) so the tarball stays. :)
#
# Add a cron job to run at 03:00 every day:
#   $ crontab -e
#   0 3 * * * bash /home/myuser/scripts/backup.sh > /var/log/backup.log 2>&1
#
# //Ulf Benjaminsson, 2018-01
if [ $(id -u) != 0 ] ; then
    echo "please run backup.sh as root" >&2
    exit 1
fi
 
HOSTNAME=$(hostname -s)
TIMESTAMP_FORMAT='%Y-%m-%d %H:%M:%S'
ARCHIVE_PWD='secret' #used for 7z encryption. Will show up in process lists.
BACKUP_OWNER='myuser'
BACKUP_GROUP='mygroup'
 
MYSQL_DUMP_USER='BACKUPUSER'
MYSQL_DUMP_PWD="secret" #will NOT be printed in logs or process lists
DB_DESTINATION='/home/myuser/mysqldump'
 
FOLDERS_TO_BACKUP='/home /etc /var/www /var/log /usr/local /usr/share/phpmyadmin /root /boot /opt'
ARCHIVE_DESTINATION='/media/backup/rotatingbackup'
 
# log(): timestamped output
# Bash version in numbers like XYYYZZZ, where X is major version, YYY is minor, ZZZ is subminor.
printf -v BV '%d%03d%03d' ${BASH_VERSINFO[0]} ${BASH_VERSINFO[1]} ${BASH_VERSINFO[2]}
if [[ ${BV} -gt 4002000 ]]; then
    log() { # Fast (builtin) but sec is highest precision for most implementations    
        printf "[%(${TIMESTAMP_FORMAT})T] %s\\n" '-1' "$*"
    }
else
    log() { # Slower, but support nanoseconds and legacy bash versions    
        echo "[$(date +"${TIMESTAMP_FORMAT}")] $*"
    }
fi
 
# which week of the month is it (1-4)?
day_num=$(date +%-d)
if (( day_num <= 7 )); then
    week_file="${HOSTNAME}-week1"
elif (( day_num <= 14 )); then
    week_file="${HOSTNAME}-week2"
elif (( day_num <= 21 )); then
    week_file="${HOSTNAME}-week3"
else # day_num < 32
    week_file="${HOSTNAME}-week4"
fi
 
# is the month odd or even?
is_even_month=$(expr $(date +%m) % 2)
if [ "$is_even_month" -eq 0 ]; then
    month_file="${HOSTNAME}-month2"
else
    month_file="${HOSTNAME}-month1"
fi
 
# create archive filename.
day=$(date +%A)
if [ "$day_num" == 1 ]; then
    archive_name=$month_file
elif [ "$day" != "Saturday" ]; then
        archive_name="${HOSTNAME}-$day"
else 
    archive_name=$week_file 
fi
 
#build the full paths before starting the real work
database_file="${DB_DESTINATION}/${archive_name}.sql.7z"
archive_file="${ARCHIVE_DESTINATION}/${archive_name}.tgz"
encrypted_archive_file="${archive_file}.7z"
 
log "Starting backup.sh"
 
if [ ! -d "${DB_DESTINATION}" ] 
then
    log "ERROR: ${DB_DESTINATION} does not exist. Skipping mysqldump."
else
    log "Dumping MySQL to ${database_file}" 
    rm -f "${database_file}" # delete any pre-existing archive manually, because 7za is a PITA.
    export MYSQL_PWD=$MYSQL_DUMP_PWD #read https://unix.stackexchange.com/a/369568 for the security implications    
    mysqldump -u ${MYSQL_DUMP_USER} --all-databases | 7za a -mhe=on -p"${ARCHIVE_PWD}" -mx=9 -si "${database_file}"
    unset MYSQL_PWD
    chown ${BACKUP_OWNER}:${BACKUP_GROUP} "${database_file}"    
fi # mysqldump
 
if [ ! -d "${ARCHIVE_DESTINATION}" ] 
then
    log "ERROR: ${ARCHIVE_DESTINATION} does not exist. Skipping backup ${archive_name}"
    log "backup.sh finished with errors!"
else
    log "Backing up ${FOLDERS_TO_BACKUP} to ${archive_file}"
    tar --use-compress-program=pigz -Pcf "${archive_file}" $FOLDERS_TO_BACKUP
        
    # delete any pre-existing encrypted archive manually, because 7za is a PITA.
    rm -f "${encrypted_archive_file}"
    
    log "Encrypting ${archive_file} to ${encrypted_archive_file}"
    7za a -mhe=on -p"${ARCHIVE_PWD}" -mx=0 "${encrypted_archive_file}" "${archive_file}"
 
    #make sure the 7z was created before deleting the tarball
    if [ -e "${encrypted_archive_file}" ]
    then    
        log "Removing unencrypted ${archive_file}"
        rm -f "${archive_file}"
        chown ${BACKUP_OWNER}:${BACKUP_GROUP} "${encrypted_archive_file}" 
    else
        chown ${BACKUP_OWNER}:${BACKUP_GROUP} "${archive_file}" 
        log "ERROR: 7z failed! Leaving unencrypted ${archive_file} on drive!"
    fi
    
    log "backup.sh finished!"
    #list files ${ARCHIVE_DESTINATION} to check file sizes. 
    ls -lh "${ARCHIVE_DESTINATION}/"
fi # archive creation

Comments

  • Gyqizv icon
    04/02/26 06:17:54 PM UTC
    text |

    0 B

    |

    0 👍

    /

    0 👎

    Best t33n active cpx link daily updates!
     Copy and paste the link in a new browser tab and then hit enter!
     https://crazyporn.@xxx/members/157354/?asgtbndr=1&play=true&spon=adworld&zone=400
     Remove the @ 
  • Yuizcko icon
    05/18/26 01:10:55 PM UTC
    text |

    0 B

    |

    0 👍

    /

    0 👎

    Best t33n active cpx link daily updates!
     Copy and paste the link in a new browser tab and then hit enter!
     https://crazyporn.xxx/members/157354/?asgtbndr=1&play=true&spon=adworld&zone=400