vaultwarden 备份思路之再也不改版

11 天前
 0o0O0o0O0o

vaultwarden 用了几年,备份方案翻来覆去折腾了好多种,这次利用 nginx syslog 实现“精确”的备份:

log_format json-log escape=json '{"status":$status,"request_method":"$request_method","request_uri":"$request_uri"}';

server {
    location / {
        # ...

        proxy_redirect off;
        proxy_pass http://vaultwarden;
        proxy_http_version 1.1;

        access_log syslog:server=syslog-server:50333,facility=local7,tag=nginx,severity=info,nohostname json-log;
    }
}

这样 syslog-server:50333 就可以收到完成的请求,可以拿到 status request_method request_uri 等信息,如此只需要实现个简单的 syslog server ,便可以根据这些信息来决定是否调用备份:例如所有 GET 请求都无需关心,因为对数据库没有更改;例如我不关心登录、注册、设备、二次验证之类的变更,则 ^/identity/accounts/prelogin ^/identity/connect/token .*/devices/.* .*/two-factor/.* 等请求也可以略过;例如我不使用 sends ,.*/sends/.* 也可以忽略。

bitwarden 客户端让每一次更改都必须对应 vaultwarden 数据库的更改,这个备份方案理论上也可以确保对自己有价值的变更都被备份。

部署运行了一周,我很喜欢这个方案

诸位觉得如何

1715 次点击
所在节点    分享创造
35 条回复
hiplon
11 天前
crontab 全局备份方案

0 3 * * * zip -r /root/wardendata.zip /root/wardendata

5 3 * * * scp /root/wardendata.zip xxx@xxx.xxx:/home/xxx/.
Xusually
11 天前
全量 zip 一下,占空间极小,没必要增加复杂度吧?
0o0O0o0O0o
11 天前
@hiplon @Xusually

我是从 cron 到 inotifywatch 再到如今的 access_log ,这些方案的变更就一个追求,就是我在文中提到的:

"确保对自己有价值的变更都被备份"

而没有 cron 那样的时间差,可以避免丢失时间间隔中的变更,因为我认为密码数据很重要,丢失一条可能都很严重,不像笔记备份数据那样我可以接受丢失一部分
terry0314
11 天前
我的 Vaultwarden 部署在群晖上,完全依赖群晖的备份了,主打一个不操心
guisheng
11 天前
不理解,首先只要存入数据库中一般客户端都会及时更新,另外即使后台服务没有开启也能使用客户端只是不能新增(这点我感觉没做好,为什么不能先保存能通讯的时候在上传呢)。所以即使我没有及时备份也不会出现数据丢失的情况吧……

另外全量备份虽然大但是可以删除之前的。我都是整个 docker 挂载目录压缩。
RiddMa
11 天前
@0o0O0o0O0o 不明白为什么丢失密码很严重,不是有“忘记密码”功能吗?按天为单位备份感觉完全足够了,又不是天天在加新的密码。要是觉得不靠谱按小时按分钟也行,反正数据库很小。

真正重要的数据不应该依赖单一的备份手段,要是有完全不能丢的东西,应该在多个介质上重复保存。
Smilencer
11 天前
我是靠虚机镜像备份...
0o0O0o0O0o
11 天前
@guisheng #5 允许本地保存的话不可避免要处理多客户端的冲突吧,不太懂,但应该挺难妥善处理的? https://www.inkandswitch.com/local-first/
0o0O0o0O0o
11 天前
@RiddMa #6

> 不是有“忘记密码”功能吗?

确实,但有的东西也许不存在一个"忘记密码"功能

> 又不是天天在加新的密码

我倒觉得这恰恰是我追求每次变更都备份的重要支撑。。。变更不频繁所以完全可以每次都备份

> 真正重要的数据不应该依赖单一的备份手段

赞同,所以这个方案并不提及具体如何备份

并且我是在每次变更后备份并发送通知汇报备份结果,变更一定是我和 bitwarden 主动交互,所以如果出现了错误或者没收到通知,我也可以在很短的时间内得知并处理
greenskinmonster
11 天前
incron (根据文件变化触发命令) -> restic (快照、压缩、加密、去重) 感觉简单也更完善
0o0O0o0O0o
11 天前
@greenskinmonster #10 感谢,学到个命令 incron

我之前用的 inotifywatch ,有些问题,例如我提到的 "登录、注册、设备、二次验证之类的变更",每次登录都会导致数据库文件变化,而我并不需要处理这种变化,access_log 方案就是对此的升级
pems002
11 天前
虽然这种自托管就是自己对自己负责,但是 Bitwarden 或者说 Vaultwarden 并没有推出一个自己真真意义上的备份功能,所以我觉得其实备份的方法就因人而异了,但是楼主这个思路其实我觉得挺好的,比我单纯 cron 一个任务把压缩包传到网盘里的思路要好的多,我再观望一下改天试试看!
drymonfidelia
11 天前
根据我长期运维 nginx 的经验,nginx 在某些特殊情况(超时、源站返回的时候中断)有概率不写 access log ,还没有定时稳定
0o0O0o0O0o
11 天前
@pems002 #12 我有在维护基于此思路的 syslog server 简单实现和 docker compose file ,包括一些容器、Nginx 加固等,不过还很早期,等我继续查阅资料学习和优化一番再来分享
drymonfidelia
11 天前
另外如果你的 :50333 因为什么原因卡死了,nginx 也不会在他恢复正常的时候重发
drymonfidelia
11 天前
备份方案还是越简单越不容易出问题,我们以前也搞得这么复杂最后到要用备份的时候发现根本没备份进去,最后花了几十万找人恢复
0o0O0o0O0o
11 天前
@drymonfidelia #13 很好的提醒,谢谢。那后面有可能自己实现一个反代,实际上这个简单反代需求也不太需要 Nginx 。
zhhmax
11 天前
当你使用客户端的时候,创建或修改的密码必然是先在客户端上保存,然后再推送到服务端。使用 cron 命令定时备份密码文件到云盘,即便是服务器挂了,客户端上已经有最新的数据,也不会有任何密码丢失的情况发生吧,除非是登录网页操作新增密码而不使用任何客户端?。且密码文件体积很小,即便是每五分钟产生一个压缩包,不会有文件量太大没有地方保存的情况出现,如果彻底删了某个密码,也能根据每 5 分钟的备份找回来,很难再想到使用 cron 命令备份还会有什么极端情况发生导致密码同步出问题/丢失密码的情况发生。
0o0O0o0O0o
11 天前
@zhhmax #18

> 当你使用客户端的时候,创建或修改的密码必然是先在客户端上保存,然后再推送到服务端

https://bitwarden.com/help/using-bitwarden-offline/

Any unlocked Bitwarden app can be used offline in read-only mode ... you won't be able to make edits to or add vault items

> 每五分钟产生一个压缩包

不赞同,我认为和编程一样,自然是越精确越好,对于一些用户来说,为了可能几天才出现一次的变更,何必用这么频繁的备份呢?
RoccoShi
11 天前
这太细了, 我都直接一把梭 cron 每天凌晨停 container 把所有 data volume 打包上传到 google drive 和 onedrive 🤣

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1050331

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX