鉴于上次的服务器崩溃事件,写一个数据自动备份脚本就显得尤为重要。折腾了一晚,最终实现效果是每晚三点自动备份数据库和网站等数据并使用Openssl加密归档,保留最近一个月的数据,通过rclone同步到Google Drive和Onedrive上,这样就万无一失了🍟

Shell脚本

脚本是自己使用,因此比较简单。

#!/bin/bash
# Writen by Atp on Nov 15, 2020
# Website:  https://www.zatp.com

DATE=`date +%Y%m%d`
BACKUP_TEMP_PATH=/backup/tmp
# Database
DB_NAME=
DB_USR=
DB_PW=
DB_OUT_NAME="db_$DATE"
# Website
WEB_PATH=
WEB_OUT_NAME="web_$DATE"
# Archive
ARCHIVE_PATH=/backup/archives
ARCHIVE_LOG_FILE=/backup/log/backup.log

# Backup mysql
# mysqldump -u$DB_USR -p$DB_PW --databases $DB_NAME > $BACKUP_TEMP_PATH/$DB_OUT_NAME.sql
mysqldump --login-path=$DB_USR --databases $DB_NAME > $BACKUP_TEMP_PATH/$DB_OUT_NAME.sql

# Backup webdsite
cd $WEB_PATH
zip -rq $BACKUP_TEMP_PATH/$WEB_OUT_NAME.zip *

# Archive files
cd $BACKUP_TEMP_PATH
# tar cf - * | openssl enc -e -aes-128-cbc -pbkdf2 -k [password] -out $ARCHIVE_PATH/$DATE.tar.aes
tar cf - * | gpg -e -r [recipient] -o $ARCHIVE_PATH/$DATE.tar.gpg

# Backup the latest 30 days
rm $BACKUP_TEMP_PATH/*
find $ARCHIVE_PATH -name "*.tar.gpg" -type f -mtime +30 -exec rm {} \;

# Sync to Google Drive
rclone sync $ARCHIVE_PATH gdrive:[sync path]

# Sync to Microsoft OneDrive
rclone sync $ARCHIVE_PATH onedrive:[sync path]

# Output log file
echo -e "\e[1;32m---------------------------------------------\e[0m" >> $ARCHIVE_LOG_FILE
echo -e "Backup date: "$(date +%Y-%m-%d)"\t""Finish time: "$(date +%H:%M:%S) >> $ARCHIVE_LOG_FILE
echo -e "\e[1;32m---------------------------------------------\e[0m\n" >> $ARCHIVE_LOG_FILE

这里说明一下,使用mysqldump备份的时候,如果通过账号密码导出会提示使用明文密码不安全的警告,虽然不影响使用,但看着就不爽,因此改用了MySQL5.7之后提供的新方式,通过--login-path=的方式登录数据库,首先保存一个加密验证信息:

mysql_config_editor set --login-path=[name] --host=localhost --user=[usr] --password

查看所设置的信息:

mysql_config_editor print --all

删除指定信息:

mysql_config_editor remove --login-path=[usr]

值得一提的,我第一次设置的时候毫无疑问的失败了- -,一直无法登录,后来才知道所设置的用户密码中不能包括"#"符号,不然就会报错。

rclone的使用方法就不再多说,网上有很多相应的教程。

定时任务

备份脚本写好之后就该定时执行了,这里通过Cron设置定时任务,每晚两点执行备份脚本:

crontab -e
00 2 * * * /backup/backup.sh

使用说明:

分 时 日 月 周 执行命令
第 1 列:分钟 0-59,每分钟用 * 或者*/1表示,整点分钟数为00或0
第 2 列:小时 0-23(0 表示 0 点)
第 3 列:日 1-31
第 4 列:月 1-12
第 5 列:星期 0-6(0 表示星期天)
第 6 列:运行的命令

Update(2020/11/21):
经研究发现,Openssl并不适合用于文档加密,因此改用GnuPG

Tags: Linux, Shell

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.