Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement