自建 Bitwarden 差点让我丢了所有密码:一次真实的数据灾难与三天重建备份体系
真实事故 + 完整复盘。如果你也在自建 Vaultwarden / Bitwarden,这篇文章可能帮你避开一个足以毁掉所有密码的坑。
事故:登录的一瞬间,密码全没了
背景:我的树莓派(跑着 Vaultwarden 密码库)SD 卡写坏 + 电源芯片烧毁,数据全丢。我在新系统上重新部署了 Vaultwarden------一个全新的、空的密码库。
然后我用原账号登录了 Bitwarden 客户端。
登录成功的那一秒,本地缓存的所有密码被清空了。
为什么会这样
这是 Bitwarden 的设计特性,不是 bug:
客户端以服务器为准(server-authoritative)。登录/同步时,服务器端数据覆盖本地缓存。服务器是空库 → 本地被"同步"成空。
更绝望的是连锁反应:
- 家里台式机:已同步,空了
- 手机:已同步,空了
- 旧 SD 卡:返厂维修,指望不上
- 公司电脑:一直连着网,但它还没打开过 Bitwarden------最后的火种
抢救:三步保命操作
第一步:立即切断同步通道
bash
docker stop vaultwarden
服务器一停,客户端连不上,本地缓存暂时不会被覆盖。
第二步:到公司后------先断网,再开客户端
这是整个抢救的关键。断网状态下打开 Bitwarden,本地缓存完好无损,全部密码都在。
第三步:立即导出加密备份
设置 → 导出 → 选加密的 JSON(带密码保护),存到安全的地方。然后才恢复网络、重启服务器、导入数据。
密码库,救回来了。
复盘:三层备份体系
事故之后,我搭了一套备份体系,分享给大家抄作业:
L1:整盘镜像(系统级)
系统完全配置好后做一次性全量镜像。关键:绝不能 dd 正在运行的系统盘,文件系统在写,镜像必然不一致。
正确姿势:SD 卡起一个临时系统 → SSD 未挂载 → 只读复制:
bash
sudo dd if=/dev/sda bs=4M status=progress conv=sparse | pigz -p 4 > /mnt/usb/backup.img.gz
sha256sum /mnt/usb/backup.img.gz > backup.sha256
恢复:pigz -dc backup.img.gz | sudo dd of=/dev/sda
L2:关键数据加密备份(自动)
密码库、代码仓库、配置文件这类"小而命重要"的数据,每周自动打包加密发邮箱:
bash
tar -czf - vaultwarden/data gitea/data configs/ \
| gpg --batch --symmetric --cipher-algo AES256 --passphrase "$PASS" -o backup.tar.gz.gpg
- GPG AES-256 对称加密,固定密码
- 脚本发邮件前会本地解密自检(加密包坏了立刻发现)
- 本地留 4 周副本 + 邮箱异地副本
- 总共 5MB 左右,邮箱附件毫无压力
L3:配置代码化(Git 管理)
所有系统配置(udev、systemd、SSH、网络、Docker 启动命令)收进 Git 仓库,推到自建 Gitea(私有库):
bash
git clone <私有仓库>
sudo ./setup.sh # 一键恢复所有系统配置
五条血泪教训
- 数据迁移铁律:新端验证完整之前,旧端一个比特都不许动
- Bitwarden 系客户端,怀疑服务器有问题时,先断网再打开------这一条值我所有密码
- 云端再可靠,也抵不过一次误操作------离线副本必须有
- 备份不验证 = 没有备份------我的备份脚本自带解密自检,恢复演练每季度一次
- 能自动化的不手工------人的记性靠不住,cron 靠得住
硬件环境
树莓派 4B(4GB)+ M.2 SSD(USB 启动),Ubuntu 24.04。全部服务 Docker 化,总内存占用 1.6GB,普通人的 homelab 完全玩得转。
这次事故的完整技术细节(Lucky 反代、通配符证书 DNS-01、单端口多服务分流)在我的博客上有系列文章,评论区可以交流。