vaultwarden 自建密码库:部署、加固与自动备份
摘要
密码管理器的选型只有一条标准:数据必须在自己手里。这篇记录 vaultwarden(Bitwarden 的轻量 Rust 实现)在 CT700 上的完整落地:Docker 部署、nps 隧道 + nginx 公网化(pwd.028000.xyz)、SIGNUPS_ALLOWED=false 关注册、登录接口限流 + fail2ban 防爆破、每日 03:30 自动备份到 NAS(保留 14 天)。重点写了为什么选 vaultwarden 而不是官方 Bitwarden、WebSocket 和附件大小的 nginx 细节,以及"备份一定要恢复演练"的教训。
目录
- 一、为什么是 vaultwarden
- 二、部署:CT700 上的 Docker
- 三、公网化:nps 隧道 + nginx
- 四、安全加固:关注册、限流、fail2ban
- 五、SIGNUPS_ALLOWED=false 的含义与用户注册流程
- 六、自动备份:每日 03:30 到 NAS
- 七、验收清单
- 八、踩坑记录
- 九、总结
一、为什么是 vaultwarden
密码管理器存的是一家人的数字身家,选型标准只有一条:数据必须在自己手里。用第三方密码服务,等于把最敏感的数据托付给别人的服务器和别人的安全团队。自建是唯一选项。
| 方案 | 结论 |
|---|---|
| Bitwarden 官方服务端 | 功能全,但重(微软系技术栈、吃资源),个人用不上那么多 |
| vaultwarden | Bitwarden 的轻量 Rust 实现,API 兼容官方客户端,一个 Docker 容器搞定,资源占用小 |
| 1Password 等商业服务 | 数据不在自己手里,直接排除 |
vaultwarden 的最大优势是客户端兼容:手机、电脑、浏览器扩展全部用 Bitwarden 官方客户端,登录时把服务器地址填成自己的 pwd.028000.xyz 就行。服务端轻量,客户端成熟,两头都占了。
二、部署:CT700 上的 Docker
vaultwarden 跑在 CT700 这个 LXC 容器里(和 OpenList 的 CT701、docker-lab 的 CT702 是邻居)。部署方式 Docker Compose,一把梭:
# docker-compose.yml(关键片段,结构示意)
services:
vaultwarden:
image: vaultwarden/server:latest
volumes:
- /opt/vaultwarden/data:/data
environment:
# 关闭公开注册,铁律
- SIGNUPS_ALLOWED=false
数据卷 /opt/vaultwarden/data 落在宿主,里面是 SQLite 数据库和附件。容器重建不丢数据,这是底线。
三、公网化:nps 隧道 + nginx
密码库要随时可用(手机上查密码是高频场景),所以必须公网化。链路:
手机/电脑 → https://pwd.028000.xyz
→ VPS 443(nginx:LE 证书,2026-12-30 到期,certbot 自动续期)
→ nps 隧道(VPS 28443 → 192.168.0.120:443,CT700)
→ vaultwarden
注意隧道目标是 CT700 的 443 端口(容器内 vaultwarden 配了 HTTPS),不是 80。这个细节别搞错。
nginx 反代有几个 vaultwarden 特有的配置点:
# 关键片段
server {
listen 443 ssl http2;
server_name pwd.028000.xyz;
# WebSocket 支持(vaultwarden 的实时同步用)
location /notifications/hub {
proxy_pass http://127.0.0.1:28443;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# 附件上传大小
client_max_body_size 500m;
location / {
proxy_pass http://127.0.0.1:28443;
}
}
WebSocket:vaultwarden 的 /notifications/hub 是实时同步通道,nginx 必须配 Upgrade 转发,否则多端同步会有延迟或异常。附件大小:client_max_body_size 500m,密码库里经常存些证书、密钥文件附件,默认的 1m 肯定不够。HTTP 301 跳 HTTPS:全站强制,密码流量不允许明文。
四、安全加固:关注册、限流、fail2ban
密码库是全家最敏感的服务,加固按最高标准:
| 措施 | 配置 | 说明 |
|---|---|---|
| 关闭公开注册 | SIGNUPS_ALLOWED=false | 公网任何人都不能自助注册,见下节 |
| 登录接口限流 | 5 次/分钟 | 防密码爆破 |
| 全站 API 限流 | 60 次/分钟 | 防刷 |
| fail2ban | vaultwarden-limit jail,10 分钟 8 次 429 封 1 小时 | 第二道防线 |
| TLS | 仅 1.2/1.3,HSTS | 传输安全 |
fail2ban 的 jail 是照着成熟模式配的:nginx 限流先挡,超限回 429,fail2ban 盯 429 日志,10 分钟内 8 次就封 IP 1 小时。这套模式在 vaultwarden 上首创,后来被复制到 OpenList、Halo、图床,全家统一。
五、SIGNUPS_ALLOWED=false 的含义与用户注册流程
SIGNUPS_ALLOWED=false 是 vaultwarden 最重要的安全开关,值得单独讲透。它的含义是:关闭公开注册接口,公网上的任何人都不能自助创建账号。注意它关的是"自助注册",不是"添加用户"——管理员还是可以邀请/创建用户的。
当时的真实操作流程是这样的:
- 部署时先保持
SIGNUPS_ALLOWED=true(或临时打开),完成初始化; - 走官方注册页创建第一个用户账号(当时给用户新建的账号);
- 确认第一个账号能正常登录、客户端同步正常;
- 把
SIGNUPS_ALLOWED改成false,重启容器; - 从公网访问注册页,确认已无法自助注册。
这个顺序不能反:如果一上来就设 false,第一个管理员账号都建不出来。以后需要给家人开账号,走管理员邀请流程,不开公开注册。账号密码用户自设,不记录明文。
六、自动备份:每日 03:30 到 NAS
密码库的备份是"丢了就全家抓瞎"级别的数据,备份策略按最高标准:
- 频率:每日 03:30,systemd timer 触发;
- 目标:NAS(CT700 内挂载 NAS 目录,备份直接写过去);
- 保留:14 天滚动;
- 内容:
/opt/vaultwarden/data整个目录(SQLite 数据库 + 附件)。
# systemd timer 示意:每天 03:30 执行备份脚本
# 备份脚本核心就是打包 + 按日期命名 + 清理 14 天前的
tar -czf /mnt/nas/backup/vaultwarden/vaultwarden-$(date +%F).tar.gz /opt/vaultwarden/data
find /mnt/nas/backup/vaultwarden/ -name "vaultwarden-*.tar.gz" -mtime +14 -delete
2026-10-01 部署当天就做了一次备份并校验通过。备份的铁律:没做过恢复演练的备份等于没备份。SQLite 文件的恢复就是停容器、解压覆盖、起容器,三步,演练一遍心里才有底。这个演练记在待办里,定期做一次。
另外注意备份时间 03:30 的选择:和 PVE 整机备份(02:00/03:00)、Google Drive 异地备份(04:00)错开,避免同一时间多个大 IO 任务打架。家里这套备份体系的时间表是统一规划过的。
七、验收清单
| 测试项 | 结果 |
|---|---|
| 公网 HTTPS 访问 | 正常,TLS 1.3 |
| HTTP 301 跳 HTTPS | 通过 |
| 注册页(关闭后) | 无法自助注册 |
| 用户登录 | 正常 |
| 客户端同步 | 正常 |
| 限流(登录接口超限) | 429 |
| fail2ban | 封禁正常 |
| 附件上传 | 正常(500m 以内) |
| 每日备份 | 03:30 正常执行,NAS 上有文件 |
端到端验收全部通过后,才算交付。密码库这种服务,"差不多能用"是不够的,必须逐项确认。
八、踩坑记录
坑 1:隧道目标端口是 443 不是 80
CT700 内的 vaultwarden 配了 HTTPS,nps 隧道要打到 192.168.0.120:443。如果按惯性打到 80,隧道通了但握手失败,表象是"隧道是好的,服务连不上"。新增隧道时先确认目标服务到底在监听哪个端口。
坑 2:WebSocket 不配,同步异常
vaultwarden 的实时同步走 /notifications/hub 的 WebSocket,nginx 不配 Upgrade 转发,表现是"能登录、能看,但多端同步延迟或不同步"。这种"半正常"的状态最难排查,因为第一反应是客户端问题。记住:vaultwarden 的 nginx 配置里,WebSocket 那一段是必备的。
坑 3:附件默认 1m 不够用
nginx 默认 client_max_body_size 1m,密码库里存个证书、密钥文件经常超。配成 500m,一步到位。所有带文件上传的服务,部署时都要检查这一项。
客户端使用指南:手机、电脑、浏览器扩展
vaultwarden 的服务端只是"仓库",日常用的是客户端。全家统一用 Bitwarden 官方客户端,登录时服务器地址填 https://pwd.028000.xyz:
| 客户端 | 说明 |
|---|---|
| 手机 App | Bitwarden 官方 App,iOS/Android,自填/指纹解锁 |
| 电脑桌面端 | 官方桌面应用,剪贴板自动清除记得开 |
| 浏览器扩展 | 最常用,自动填充、右键生成密码 |
三个习惯要养成:主密码足够强(它是唯一钥匙,丢了谁也找不回来)、开两步验证(TOTP,存在手机验证器里)、定期导出备份(加密 JSON,存 NAS 私密配置)。密码管理器本身的安全,靠的是主密码 + 2FA,服务端加固只是外层。
组织与分享:家庭密码管理
密码多了要分类,vaultwarden 支持文件夹和组织(Organization):
- 按"个人/家庭/工作"建文件夹,条目多了不迷路;
- 家庭共用的账号(宽带、NAS、视频会员),建组织共享给家人,不用微信发密码;
- 每个条目写清用途和备注,半年后自己还看得懂。
组织分享的权限分"可看/可改",默认给可看。家人离席(比如孩子长大分家),组织里移除就行,不用一个个改密码。
密码学的常识:主密码与零知识
vaultwarden 的安全,建立在两个密码学常识上,值得每个用户理解。
主密码是唯一的钥匙。 vaultwarden(和 Bitwarden)是"零知识"架构:你的主密码在本地派生出加密密钥,密码库在本地加密后,才上传到服务器。服务器存的是密文,没有你的主密码,服务器自己也解不开。这意味着:主密码丢了,谁也找不回来——包括你自己,没有"找回密码"。主密码的强度,就是整个密码库的强度。建议:四个随机单词的组合(比如"正确-马-电池-订书钉"那类),好记又够强。别用生日、别用重复密码。
两步验证是第二把锁。 主密码再强,也怕键盘记录、钓鱼。TOTP 两步验证(手机验证器 6 位数)堵的是"密码泄露":攻击者拿到你的主密码,没有你的手机,还是进不去。开 2FA 的代价是每次登录多输 6 位数,收益是"密码泄露也不丢库"。这笔账,划算。注意:2FA 的恢复码要抄下来存好(NAS 私密配置),手机丢了靠它救命。
零知识的边界:零知识保护的是"服务器看不到你的密码",不保护"你的设备被黑"。手机中了木马,键盘记录把主密码偷了,零知识也救不了。所以设备安全(系统更新、不装来路 App)和主密码安全是一体的。密码管理器解决的是"密码太多记不住"的问题,不是"设备被黑"的问题。分清边界,才能正确使用。
家庭密码管理的分工:谁管什么
密码库搭好了,家庭密码管理还要分工。不然密码库变成"你一个人的",家人继续用"123456"。
分工一:管理员(你)。 管 vaultwarden 的服务端(备份、升级、加固)、管组织(建共享、拉人踢人)、定规矩(主密码强度、2FA 必须开)。技术的事,你全包。
分工二:家人。 只做三件事:装客户端、设强主密码、开 2FA。别让他们管服务端,别让他们记服务器地址(浏览器收藏夹存好)。家人的学习成本,压到最低:能自动填充,就别让他们复制粘贴。
分工三:应急。 万一你不在,家人要查密码,怎么办?应急方案:指定一个"应急联系人"(比如配偶),他的 vaultwarden 账号在组织里,能看到家庭共享的密码;你的个人密码,写一份纸质 sealed(信封封好,存保险箱),注明"紧急时拆"。纸质是最后的兜底,平时不用,关键时救命。
分工四:交接。 密码库的" root 权限"(vaultwarden 管理员、NAS 私密配置),要有一个交接文档:万一你长期不在,谁接手、怎么接手。文档存 NAS 私密配置,家里人知道在哪。这不是悲观,是负责。数字遗产,和实体遗产一样,要安排。
密码管理的终点,不是"技术多牛",是"家人会用、出事有人接"。技术是手段,人才是目的。
主密码忘了:真的没办法
零知识架构下,主密码忘了,密码库就是一堆打不开的密文。没有"找回密码",没有"客服重置"。唯一的救命稻草:2FA 恢复码 + 应急纸质备份。2FA 恢复码能让你在丢手机时重设验证器,但主密码忘了,恢复码也救不了。所以主密码的备份,是"纸质 sealed 信封存保险箱"级别的事。写下来,封好,放好。这不是"不安全",这是"权衡":纸质丢了的概率,远小于"忘了主密码"的概率。两害相权,纸质赢。
九、总结
vaultwarden 的落地链条:轻量选型(Rust 实现、兼容官方客户端)→ Docker 部署 → nps 隧道 + nginx 公网化(WebSocket、500m 附件、301 跳转)→ 关注册 + 限流 + fail2ban 三层加固 → 每日 03:30 自动备份到 NAS。密码库是全家安全体系的"根",它的加固模式(限流 + fail2ban)后来成了全家的统一标准。记住两条铁律:SIGNUPS_ALLOWED=false 常年开启;备份不做恢复演练等于没备份。
相关阅读:《WireGuard 组网实战:把管理面板藏进 VPN》、《fail2ban 实战:从 SSH 到 Web 登录接口的防护》。