家庭服务器备份体系
基于 PVE cron + GitHub + OneDrive 的家庭服务器自动化备份与灾难恢复体系设计,含加密、保留策略和恢复流程。
#type / howto
#status / evergreen
#tech / ops
#platform / server
家庭服务器备份体系
[!info] related notes
设计目标
任意一台服务器故障后,把一台新服务器的连接方式(IP + 凭据)交给 AI 或人类操作员,即可依据备份数据全自动恢复该节点的状态。
核心约束:所有 VM 跑在同一台 N100 物理机上(PVE 宿主),物理机报废 = 全部 VM 丢失。因此恢复能力完全依赖异地备份。
备份链架构
PVE root crontab (每日 03:00)
│
├─[1] 备份 PVE 本机配置(interfaces, storage.cfg, qemu-server/*.conf, crontab)
├─[2] scp 抓取 ImmortalWrt /etc/config/*(两台路由)
├─[3] rsync 抓取 Debian /opt/docker/(排除数据库大文件)
├─[4] git commit + push → GitHub(配置层,明文)
└─[5] ssh 触发 Debian upload_db.sh:
停容器 → tar 打包数据 → AES-256 加密 → rclone 传 OneDrive → 重启容器
└─ 每周日额外执行 retention.sh 清理过期归档
两层存储分工:
| 层 | 存储 | 内容 | 特点 |
|---|---|---|---|
| 配置层 | GitHub 私有仓库 | 所有节点的配置文件、compose 编排、脚本 | 明文、版本化、可 diff |
| 数据层 | OneDrive | 数据库、证书、密钥等运行时数据 | AES-256-CBC 加密、按日归档 |
加密方案
- 算法:
openssl enc -aes-256-cbc -salt -pbkdf2 - 密码:48 字符随机 base64 串,存放在 Debian
/root/.backup-passphrase - 每个归档附带
.sha256校验和,恢复时先验证完整性再解密 - 密码的离线副本保存在密码管理器中(不在仓库内)
选择 openssl 而非 GPG 的原因:服务器环境天然有 openssl,无需额外安装;对称加密足够(不需要公钥分发);PBKDF2 提供抗暴力破解能力。
保留策略
采用 7-4-6 策略平衡空间与恢复窗口:
- 最近 7 天:每日归档全保留
- 最近 4 周:每周日归档保留
- 最近 6 个月:每月 1 号归档保留
- 其余自动删除
实现方式:retention.sh 用 date 计算保留集合,生成待删文件列表,一次性 rclone delete --files-from 批量清理(避免逐个删除的 API 限速)。
恢复流程概要
Debian Docker Host
- 新装系统 + Docker
- 配置 GitHub SSH key → clone 仓库 → 恢复 /opt/docker 配置
- 配置 rclone OneDrive → 下载最新 .enc 归档
- SHA256 校验 → openssl 解密 → tar 解压到对应目录
docker compose up -d→ 验证服务 → 恢复备份链
ImmortalWrt 路由
通过 LuCI 网页恢复备份(SSH 密码登录有 dropbear bug),或逐文件对照仓库中的 UCI 配置恢复。
PVE 整体重建
新硬件装 PVE → 恢复配置 → 按 qemu-server/*.conf 创建 VM → 各 VM 内部按上述流程恢复。
引导密钥问题(Bootstrap Secrets)
全新服务器恢复时需要三类不在仓库中的凭据:
- GitHub deploy key(能 clone 私有仓库)
- rclone OneDrive token(能访问云盘)
- 备份加密密码(能解密 .enc 归档)
这些凭据的离线副本保存在密码管理器(Vaultwarden)中。这形成一个有趣的递归:Vaultwarden 本身的恢复也需要这些凭据——因此必须有一份独立于服务器的离线副本。
经验与踩坑
- PVE 是单点:所有 VM 在同一物理机上,给 Debian 加独立 timer 无意义(PVE 挂了 Debian 也挂)。异地副本(GitHub + OneDrive)才是真正的风险缓解。
- Windows git-bash 下 ssh 嵌套引号/heredoc 必碎:远程执行固定用「本地写脚本 → scp → ssh bash /tmp/x.sh」模式。
- sha256sum 生成时用绝对路径会导致异地验证失败:必须
cd到文件所在目录再用相对路径生成。 - rclone 逐个 delete 200+ 文件会超时:改用
--files-from批量操作。 - ImmortalWrt dropbear SSH 密码登录 bug:密码正确但被拒绝,只能用 LuCI/ubus 管理。
- 恢复时必须先还原数据再启容器:否则 Vaultwarden 会初始化空库覆盖。
维护节奏
- 每日 03:00 自动执行(无需人工干预)
- 超过 48 小时无 GitHub commit = 备份链断了,需排查
- 每季度做一次恢复演练(restore-drill.sh,不影响线上数据)
- OneDrive OAuth token 90 天过期,届时需
rclone reconnect