用 Restic 加密备份到 S3 兼容存储(含还原演练)

Restic 是单文件 Go 二进制,做客户端加密 + 内容寻址 dedup + 增量备份。
对比 rsync 优势:

  • 加密在客户端完成,存储端只能看到加密块
  • 强 dedup:跨快照 / 跨主机 / 跨文件位置都生效
  • 任何 S3 兼容存储(AWS S3 / Backblaze B2 / Wasabi / minio / Cloudflare R2)都支持
  • 单二进制零运行时依赖

安装

# Debian / Ubuntu 自带的版本一般偏旧,建议直接装官方二进制
RESTIC_VER=0.17.3
ARCH=$(dpkg --print-architecture)   # amd64 / arm64
curl -fsSL "https://github.com/restic/restic/releases/download/v${RESTIC_VER}/restic_${RESTIC_VER}_linux_${ARCH}.bz2" \
  | bunzip2 > /usr/local/bin/restic
sudo chmod +x /usr/local/bin/restic
restic version

初始化仓库(一次)

以 Backblaze B2 为例(最便宜的 S3-API 兼容方案之一):

export B2_ACCOUNT_ID=...
export B2_ACCOUNT_KEY=...
export RESTIC_REPOSITORY=b2:my-bucket:/host-foo
export RESTIC_PASSWORD=$(openssl rand -base64 32 | tr -d '\n')
echo "$RESTIC_PASSWORD" | sudo tee /etc/restic.pw && sudo chmod 600 /etc/restic.pw

restic init

RESTIC_PASSWORD 丢了仓库就回不来了,没有任何官方 recover —— 一定要
把它存到一个独立的 password manager / 离线纸质备份。

备份脚本

#!/usr/bin/env bash
# /usr/local/sbin/restic-backup.sh
set -euo pipefail

export B2_ACCOUNT_ID=...
export B2_ACCOUNT_KEY=...
export RESTIC_REPOSITORY=b2:my-bucket:/host-$(hostname -s)
export RESTIC_PASSWORD_FILE=/etc/restic.pw

restic backup \
  --tag daily \
  --exclude-file /etc/restic.exclude \
  /etc /srv /home/yourname/projects

# 保留策略:每日 7、周 4、月 12、年 5
restic forget --prune \
  --keep-daily 7 --keep-weekly 4 \
  --keep-monthly 12 --keep-yearly 5

# 完整性校验(采样 10%,全量太慢)
restic check --read-data-subset=10%

/etc/restic.exclude 例:

node_modules
__pycache__
*.pyc
.cache
.venv
venv
target
build
dist

systemd timer

# /etc/systemd/system/restic-backup.timer
[Timer]
OnCalendar=*-*-* 02:30:00
RandomizedDelaySec=1h
Persistent=true
[Install]
WantedBy=timers.target

还原演练(重要——做一次)

# 列出所有快照
restic snapshots

# 列某个快照的文件
restic ls latest /etc

# 还原某文件到临时目录
restic restore latest --include /etc/nginx --target /tmp/restore-test

# 直接挂载为只读 FUSE
mkdir /tmp/rmount
restic mount /tmp/rmount &
ls /tmp/rmount/snapshots/
fusermount -u /tmp/rmount

至少每季度做一次完整还原演练到一台不同的机器,确认凭据和流程都对。
未经演练的备份等于没有备份。

监控

加在脚本末尾:

# 通知 healthchecks.io 跑完了
curl -fsSL --retry 3 "https://hc-ping.com/<uuid>"

# 或者推 Prometheus pushgateway
cat <<EOF | curl --data-binary @- http://pushgw:9091/metrics/job/restic/host/$(hostname)
restic_backup_last_success_time $(date +%s)
restic_backup_last_size_bytes $(restic stats latest --mode raw-data --json | jq .total_size)
EOF

踩过的坑

  • 第一次备份会很慢(全量上传),后续增量秒级;不要担心。
  • restic prune 在大仓库(TB 级)上非常慢且 I/O 密集;改成
    restic forget --keep-* --prune-max-unused 5% 限制每次 prune 范围。
  • 仓库锁残留:客户端被 kill 后会留 lock-* 文件,下次报"repo is locked"。
    确认没有其他进程后 restic unlock
  • B2 / R2 的 API 调用收费在小文件场景容易超出预期,配 restic backup --pack-size 32
    增加 pack 大小(默认 16 MB)能减少调用次数。
精确评价 共 0 人评价
可复现性
可复现 · 0 不可复现 · 0
文风
文风流畅 · 0 文风晦涩 · 0
立场
支持 · 0 反对 · 0

登录后即可对本帖作出评价。

评论区 0 条 · 所有人可在此交流

登录后参与评论。

还没有评论,来说两句。