跳转到内容

加密增量备份 ​

时间机器负责本地那一份。异地那一份需要满足两个额外条件:内容在离开你手之前就已加密,以及只传输变化部分(否则每次几百 GB 没法接受)。

这一篇用 restic 做例子。它是开源命令行工具,默认加密,自动去重,可以把仓库放在外置硬盘、NAS 或云存储上。

开始之前 ​

需要读过备份策略,并已安装 Homebrew。全部练习在一个临时仓库上进行,不动你现有的备份。

先把密码问题解决掉。 仓库密码丢失意味着里面的数据永久无法读取——没有找回机制。开始之前,先在密码管理器里建一条记录,见凭据管理。

安装 ​

sh
brew install restic

概念:仓库与快照 ​

restic 的模型只有两层:

  • 仓库(repository):存放备份数据的地方,整体加密。
  • 快照(snapshot):某一次备份的记录,可以单独浏览和恢复。

相同的数据块在仓库里只存一份,所以第二次之后的备份既快又小。这和上一节讲的 APFS 快照是不同的东西——那个在本机文件系统层面,这个是独立仓库。

建立仓库 ​

sh
restic init --repo /Volumes/备份盘/restic-repo

init 初始化一个新仓库,--repo 指定位置。命令会要求你设置密码并再输一次确认。

这个密码就是整个仓库的钥匙。设好之后立刻存进密码管理器,不要指望自己记得住。

第一次备份 ​

sh
restic --repo /Volumes/备份盘/restic-repo backup ~/Documents

backup 后面跟要备份的路径,可以写多个。第一次会完整读取,之后只处理变化的部分。

排除不需要的内容:

sh
restic --repo /Volumes/备份盘/restic-repo backup ~/Documents \
  --exclude="*.tmp" --exclude="node_modules"

--exclude 可以重复使用,行末的 \ 表示命令在下一行继续。排除项多起来时写进文件:

sh
restic --repo /Volumes/备份盘/restic-repo backup ~/Documents \
  --exclude-file=~/.restic-excludes

--exclude-file 指定一个每行一条规则的文本文件。

少打一点字 ​

每条命令都写 --repo 很烦。用环境变量:

sh
export RESTIC_REPOSITORY=/Volumes/备份盘/restic-repo

export 设置环境变量,在当前终端会话里有效。写进 zsh 配置就能长期生效,见zsh 启动文件。

密码也可以用 RESTIC_PASSWORD 传,但不要这么做——环境变量会出现在进程列表和 shell 历史里。用文件方式:

sh
restic --password-file ~/.restic-password snapshots

并且把这个文件的权限收紧:

sh
chmod 600 ~/.restic-password

600 表示只有你自己能读写,见权限与扩展属性。

这个文件绝对不能进版本库。 把它放在仓库目录之外,或者确认它在 .gitignore 里——相关讨论见dotfiles 管理里「什么不该放进去」一节。

查看与恢复 ​

列出所有快照:

sh
restic snapshots

输出里每条快照有一个 ID、时间和备份路径。

浏览某个快照的内容:

sh
restic ls latest

latest 是一个特殊名字,指最新的快照。

恢复:

sh
restic restore latest --target ~/restore-test

--target 指定恢复到哪个目录。恢复到一个新目录而不是原位置,这样可以先核对再决定,不会覆盖现有文件。

只恢复其中一部分:

sh
restic restore latest --target ~/restore-test --include "/Users/你的用户名/Documents/某个文件.pdf"

--include 按路径筛选,路径要写快照里记录的完整形式(用 restic ls latest 能看到)。

检查仓库完整性 ​

这一步很多人跳过,但它正是「备份到底能不能用」的答案。

sh
restic check

验证仓库的结构与元数据是否一致。加上数据校验:

sh
restic check --read-data-subset=5%

--read-data-subset 随机抽取一定比例的实际数据块做校验。全量校验(--read-data)要读完整个仓库,慢但彻底;抽样版适合定期跑。

建议节奏:每月一次 check,每季度一次抽样校验,以及每季度一次真实恢复。

清理旧快照 ​

不清理的话仓库会一直长大。

sh
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune

各参数的含义是保留最近 7 天的每日快照、4 个每周快照、12 个每月快照。--prune 在标记之后真正删除不再被引用的数据块。

先不加 --prune 跑一次,看清楚它打算删掉哪些:

sh
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --dry-run

--dry-run 只演练不执行。这和文件监听与批处理里强调的是同一个习惯:任何会删东西的命令,先看清单。

让它自动跑 ​

写一个 LaunchAgent 定时执行,见用 launchd 让任务按时间和事件运行。三个要点:

  1. 务必配置 StandardErrorPath。 静默失败的备份比没有备份更危险——你以为有,实际没有。
  2. 备份目标不在时要能优雅退出。 外置盘没插上时 restic 会报错,这是正常的,但要能从日志里分辨「盘没插」和「备份真的失败了」。
  3. 首次运行前在终端手工跑一次。 备份桌面、文稿这些目录需要隐私授权,后台没人能点「允许」,见 TCC 隐私授权。

其他选择 ​

restic 不是唯一选项。同类工具里 borg 也常见,特点相近;rclone 更偏向与云存储同步,加密是可选的而非默认。

选哪个都行,但有两条不能让步:内容在离开本机之前就加密,以及你真的从中恢复过一次。

检查结果 ​

用一个可丢弃的仓库走完整流程:

sh
mkdir -p /tmp/restic-demo/src && echo "hello" > /tmp/restic-demo/src/a.txt
restic init --repo /tmp/restic-demo/repo
restic --repo /tmp/restic-demo/repo backup /tmp/restic-demo/src
restic --repo /tmp/restic-demo/repo snapshots

最后一条能列出一个快照,说明链路通了。

sh
restic --repo /tmp/restic-demo/repo restore latest --target /tmp/restic-demo/out
cat /tmp/restic-demo/out/tmp/restic-demo/src/a.txt

应当输出 hello。注意恢复出来的路径保留了完整的原始目录结构,这是 restic 的行为,不是出错。

动手练习 ​

在临时仓库上验证增量和加密这两个特性:

  1. 用上面的命令建好仓库并备份一次。
  2. 修改 a.txt,再备份一次,对比两次的耗时和新增数据量。
  3. 执行 restic --repo /tmp/restic-demo/repo snapshots,确认有两个快照。
  4. 恢复第一个快照(用它的 ID 替换 latest),确认拿回的是修改前的内容。
  5. 用 grep -r hello /tmp/restic-demo/repo 在仓库目录里搜索明文,确认搜不到——数据确实是加密存放的。
  6. rm -rf /tmp/restic-demo 清理。

成功标准是第 4 步和第 5 步:能恢复到任意历史时点,并且仓库本身即使被别人拿到也读不出内容。这两点正是异地备份能放心存在别处的前提。

返回数据、备份与远程