背景

最近黑五刚结束,又买了几台服务器。这纯属是因为担心当前服务器提供商的稳定性(因为原本的商家把业务出售给了当前的这家公司),最终在一次次错过价格美丽的 Offer 之后(时差问题导致好价格都在半夜😭),还是回来选择了 drServer 这一个老牌商家。

而在迁移服务器的过程中,发现了备份不方便的问题。以前都是自己写一个脚本,把网站文件、MySQL 数据库一起压缩,然后用 Rclone 上传到 Dropbox 云盘。这个方案在以前还是能满足我的需求的,但是最近服务器上又多跑了几项服务,这时候备份的东西就多了,在 Bash 脚本里手动配置压缩、整理等功能实在有些麻烦。于是我就在想有没有一个程序,能够做到增量备份、加密备份到云端?

在一翻搜索下,我选择了 Restic 这个软件。

介绍 Restic

Restic 是一个备份工具,使用 AES-256 和 HMAC-SHA256 加密保证数据安全,在传输过程中始终保持加密。同时通过分块算法,可以实现数据去重,实现增量备份。更重要的是还支持多种后端,默认发行版内部支持的就有本地文件系统、SFTP、Wasabi、Amazon S3、Backblaze B2 等后端,此外还能结合 Rclone 实现备份到各种各样的后端。

安装 Rclone 和 Restic

Rclone 官网提供了自动安装脚本,需要保证系统已经安装了 sudo 和 unzip,具体命令如下:

sudo -v ; curl https://rclone.org/install.sh | sudo bash

而 Restic 一般都包含在系统的软件包仓库中,直接输入对应的命令安装,例如 Debian 系统:

apt install restic -y

如果你的系统发行版跟不上最新的版本,也可以在 Release 页面下载最新的版本:

https://github.com/restic/restic/releases/download/v0.17.3/restic_0.17.3_freebsd_amd64.bz2
bunzip2 restic_0.17.3_freebsd_amd64.bz2
chmod +x restic_0.17.3_linux_amd64
mv restic_0.17.3_linux_amd64 /usr/bin/

配置 Rclone

在服务器中配置 Rclone 的时候,如果使用类似 OneDrive 和 Dropbox 等需要登录授权(需要浏览器)的云端存储,需要在本地电脑上也安装相同版本 Rclone 用于认证,安装方法也与上述类似,下载解压即可。

Rclone 配置很简单,下面是一个简单的设置 OneDrive 的例子:

rclone config

# 输入 n 新建远程
e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q> n

# 输入远程名字
Enter name for new remote.
name> onedrive

# 输入远程类型
Type of storage to configure.
Enter a string value. Press Enter for the default ("").
Choose a number from below, or type in your own value.
# 省略远程列表,你可以在 Rclone 文档查看
Storage> onedrive

# 接下来两项 OAuth 直接回车跳过
OAuth Client Id.
Leave blank normally.
Enter a value. Press Enter to leave empty.
client_id> 

OAuth Client Secret.
Leave blank normally.
Enter a value. Press Enter to leave empty.
client_secret> 

# 选择 OneDrive 区域
Choose national cloud region for OneDrive.
Choose a number from below, or type in your own value of type string.
Press Enter for the default (global).
 1 / Microsoft Cloud Global
   \ (global)
 2 / Microsoft Cloud for US Government
   \ (us)
 3 / Microsoft Cloud Germany
   \ (de)
 4 / Azure and Office 365 operated by Vnet Group in China
   \ (cn)
region> global

# 回车跳过编辑高级配置
Edit advanced config?
y) Yes
n) No (default)
y/n> 

# 配置认证,如果你的服务器带有浏览器,那么可以输入 y 使用默认方式认证,如果不支持,输入 n
Use web browser to automatically authenticate rclone with remote?
 * Say Y if the machine running rclone has a web browser you can use
 * Say N if running rclone on a (remote) machine without web browser access
If not sure try Y. If Y failed, try N.

y) Yes (default)
n) No
y/n> n

# 提示需要在本地配置
For this to work, you will need rclone available on a machine that has
a web browser available.
For more help and alternate methods see: https://rclone.org/remote_setup/
Execute the following on the machine with the web browser (same rclone
version recommended):
        rclone authorize "onedrive"
Then paste the result.
Enter a value.
config_token> 

# 这里开始使用本地的 Rclone 进行认证,如果你配置的网盘需要魔法访问,请自行配置浏览器以及 Rclone 的魔法
rclone authorize "onedrive"

# 认证完成后,会出现类似的内容
2024/12/05 18:50:24 NOTICE: If your browser doesn't open automatically go to the following link: http://127.0.0.1:53682/auth?state=xxxx
2024/12/05 18:50:24 NOTICE: Log in and authorize rclone for access
2024/12/05 18:50:24 NOTICE: Waiting for code...
2024/12/05 18:50:28 NOTICE: Got code
Paste the following into your remote machine --->
{"access_token":"xxxx"....}
<---End paste

# 这时候复制本地 Rclone 输出内容的 {"access_token":"xxxx"....} 部分到服务器
For this to work, you will need rclone available on a machine that has
a web browser available.
For more help and alternate methods see: https://rclone.org/remote_setup/
Execute the following on the machine with the web browser (same rclone
version recommended):
        rclone authorize "onedrive"
Then paste the result.
Enter a value.
config_token> {"access_token":"xxxx"....}

# 选择连接类型
Type of connection
Choose a number from below, or type in an existing value of type string.
Press Enter for the default (onedrive).
 1 / OneDrive Personal or Business
   \ (onedrive)
 2 / Root Sharepoint site
   \ (sharepoint)
   / Sharepoint site name or URL
 3 | E.g. mysite or https://contoso.sharepoint.com/sites/mysite
   \ (url)
 4 / Search for a Sharepoint site
   \ (search)
 5 / Type in driveID (advanced)
   \ (driveid)
 6 / Type in SiteID (advanced)
   \ (siteid)
   / Sharepoint server-relative path (advanced)
 7 | E.g. /teams/hr
   \ (path)
config_type> onedrive

# 选择存储,只有一个直接回车
Select drive you want to use
Choose a number from below, or type in your own value of type string.
Press Enter for the default (3b77920c014c26b3).
 1 /  (personal)
   \ (3b77920c014c26b3)
config_driveid> 

# 确认存储是否正确,可以打开下面的 URL 确认
Drive OK?

Found drive "root" of type "personal"
URL: https://onedrive.live.com/?cid=xxxx

y) Yes (default)
n) No
y/n> y

# 回车确认完成
Configuration complete.
Options:
- type: onedrive
- token: {"access_token":"xxxx"....}
- drive_id: xxxx
- drive_type: personal
Keep this "one" remote?
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d> 

初始化 Restic 仓库

Restic 可以搭配 Rclone 直接在远程初始化仓库,具体是:

export RESTIC_REPOSITORY="rclone:onedrive:backup" # 备份后端
export RESTIC_PASSWORD="your-password" # 备份后端密码
restic -r rclone:onedrive:backup init

这里命令格式是 restic -r rclone:<远程名称>:<远程路径> init

(就是这么简单,相比起来 Rclone 的配置真是繁琐啊 😓)

创建 Restic 备份忽略规则

如果你想不去备份某些文件夹和文件,可以创建一个 .resticignore 文件(其实什么文件名都可以),下面给出一个简单的例子:

*.log
temp/
tmp/
log/

例子里忽略了 .log 文件、log 文件夹,以及临时文件夹,你也可以参考官方文档写出符合你自己的规则。

编写备份脚本

配置好之后,当然是写一个脚本进行备份了,否则还要在 crontab 里写一堆的命令,下面是我写的一个简单脚本:

#!/bin/bash

# 环境变量
export RESTIC_REPOSITORY="rclone:onedrive:backup" # 备份后端
export RESTIC_PASSWORD="your-password" # 备份后端密码
export EXCLUDE_FILE="/path/to/.resticignore" # .resticignore 文件地址

# 定义要备份的目录(每个目录单独一行)
directories=(
  "/folder1"
  "/folder2"
)

if [ "$1" == "backup" ]; then
    echo "开始备份..."
    # 执行备份(所有目录一起备份,并排除.resticignore中列出的内容)
    restic backup "${directories[@]}" --exclude-file "$EXCLUDE_FILE"
    echo "备份完成!"
elif [ "$1" == "forget" ]; then
    echo "开始清理早于 $2 天的备份..."
    restic forget --keep-daily $2 --prune
    echo "清理完成!"
elif [ "$1" == "list" ]; then
    restic snapshots
elif [ "$1" == "del" ]; then
    restic forget $2 --prune
else
    echo -e "\n请输入参数,例如:\nbackup --- 开始备份\nforget <n> --- 清理n天前的备份\nlist --- 列出备份\ndel <id> --- 删除指定备份\n"
fi

直接执行脚本就能看到使用提示:

请输入参数,例如:
backup --- 开始备份
forget <n> --- 清理n天前的备份
list --- 列出备份
del <id> --- 删除指定备份

恢复备份

这里只介绍恢复最新的备份,也只需要几条简单的命令:

export RESTIC_REPOSITORY="rclone:onedrive:backup" # 备份后端
export RESTIC_PASSWORD="your-password" # 备份后端密码
restic restore latest --target /path/to/restore

参考资料