Vaultwarden 密码管理

以下是根据你现有环境(1 GB 内存、Docker + Nginx + 已有 HTTPS 证书)定制的完整 Vaultwarden 私有化方案。核心判断是:Vaultwarden 实际运行内存约 50 MB,在 1 GB 总内存中完全可行,但需要给它一个温和的上限(128 MB),避免异常时挤占你已有的 trilium、git 等容器。


方案总览

层面选择理由
服务端Vaultwarden(vaultwarden/server,固定版本号)兼容官方 Bitwarden 全部客户端,单容器,资源占用极低
入口复用你现有的 Nginx + 已有 TLS 证书HTTPS 是强制要求,官方客户端拒绝非 HTTPS 连接
浏览器Bitwarden 官方 Chrome 扩展填入自托管地址,自动填充体验与云版一致
安卓Bitwarden 官方 App系统级自动填充 + 生物识别解锁
PC 桌面Bitwarden 官方桌面应用登录时选择自托管环境,填入域名
敏感信息身份 / 卡片 / 安全笔记 + 隐藏自定义字段非登录类信息统一入库,核心秘密二次主密码保护
内存约束容器限制 128 M给 1 GB 总内存留足缓冲,不威胁其他服务

一、服务端部署(贴合你现有 compose 风格)

在你的 docker-compose.yml 中新增一个 service。关键点:端口只绑定到 127.0.0.1,不直接暴露到宿主机以外,所有外部流量强制经过 Nginx。

services:
  vaultwarden:
    image: vaultwarden/server:1.37.5   # 固定版本,不用 latest
    container_name: vaultwarden
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"            # 仅本机可访,由 Nginx 反代
    volumes:
      - ./vaultwarden-data:/data
    environment:
      - DOMAIN=https://vault.你的域名.com   # 必须与最终 HTTPS 地址完全一致
      - SIGNUPS_ALLOWED=true           # 首次注册用,注册完成后立即改 false
      - ADMIN_TOKEN=用 openssl rand -base64 48 生成的长随机串
      - WEBSOCKET_ENABLED=true
      - TZ=Asia/Shanghai
    networks: [ghost_net]
    deploy:
      resources:
        limits:
          memory: 128M

启动后先用 docker compose up -d 确认容器健康,再配置 Nginx。


二、Nginx 反向代理(HTTPS 入口)

你已有 Nginx 和证书,只需为 Vaultwarden 加一个 server 块。WebSocket 升级头必须补全,否则客户端的实时同步可能异常。

server {
    listen 443 ssl;
    server_name vault.你的域名.com;

    ssl_certificate     /path/to/your/fullchain.pem;
    ssl_certificate_key /path/to/your/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # WebSocket 升级(Vaultwarden 实时同步依赖)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

X-Forwarded-Proto $scheme 这一行不可省略。Vaultwarden 需要它来确认外部访问确实是 HTTPS,否则部分客户端功能会受限。


三、安全加固:三件必做的事

1. 注册后立即关闭开放注册

这是整个部署中最容易遗漏的关键步骤。首次在浏览器访问 https://vault.你的域名.com 注册账号后,马上把 SIGNUPS_ALLOWED 改为 false 并重启容器。密码库的域名很容易被扫描到,保持开放注册等同于允许陌生人在你的服务器上创建账号。

2. 主密码单独记录,服务端不保存

Vaultwarden 的服务端不存储主密码,解密只在客户端发生。一旦丢失主密码,所有数据永久不可恢复,没有任何后门。建议使用足够长的短语式主密码,并把它记录在物理位置或另一个独立的保险渠道中,不要只放在这个密码库里。

3. 备份策略:不要直接 cp 运行中的 SQLite

Vaultwarden 默认使用 SQLite,数据文件是 ./vaultwarden-data/db.sqlite3。直接复制正在写入的数据库可能得到损坏的文件。推荐方式:

# 先停容器,再备份整个 data 目录(最稳妥)
docker compose stop vaultwarden
tar czf vaultwarden-backup-$(date +%F).tar.gz ./vaultwarden-data
docker compose start vaultwarden

如果不想停机,使用 SQLite 的在线备份命令:

sqlite3 ./vaultwarden-data/db.sqlite3 ".backup './vaultwarden-data/backup-$(date +%F).sqlite3'"

备份必须包含整个 data 目录,而不仅仅是 db.sqlite3,因为附件、config.json 和 rsa_key 也在这里面。在正式存入任何关键信息之前,先做一次恢复演练,确认备份可用。


四、客户端配置(三端统一)

所有 Bitwarden 官方客户端的配置逻辑一致:先在登录界面把服务器地址切换为自托管,再登录。如果直接输入账号密码,客户端会默认连到 Bitwarden 官方云。

Chrome 扩展

安装 Bitwarden 官方扩展后,在登录界面找到“自托管环境”(Self-hosted environment),填入 https://vault.你的域名.com。登录后进入扩展的 设置 → 自动填充,确保自动填充功能已启用。同时在 Chrome 设置中将默认密码管理器切换为 Bitwarden,否则 Chrome 内置的密码库会和扩展产生填充冲突。

安卓 App

安装 Bitwarden App,登录时选择自托管,填入相同域名。登录后:

  1. 系统设置 → 语言和输入法 → 自动填充服务 → 选择 Bitwarden;
  2. 在 Bitwarden App 内开启 自动填充服务 和 内联自动填充;
  3. 在 设置 → 账户安全 → 解锁选项 中开启生物识别解锁(指纹/面部),日常使用不必反复输入长主密码。

如果自动填充几天后失效,通常是安卓省电策略杀掉了后台服务,把 Bitwarden 的电池优化设为“不受限制”即可。

PC 桌面端

从 Bitwarden 官网下载桌面应用,登录时同样选择自托管并填入域名。桌面端的配置与手机端一致,无需额外步骤。


五、敏感信息存放策略(核心部分)

你需要在 Vaultwarden 中保管的不只是登录凭据,还包括 API Key、Token、卡号、证件号、地址、电话。关键在于用对条目类型,并把真正需要保护的值放进“隐藏自定义字段”。

推荐映射

信息类型条目类型存放方式
登录账号/密码登录内置字段,用于自动填充
银行卡号卡片内置卡号、有效期;CVV 可另设隐藏字段
身份证/护照号身份不要填入预设的明文证件号字段;为每种证件号新建隐藏自定义字段
地址 / 电话身份直接使用内置字段,属于结构性信息,通常无需隐藏
API Key / Token安全笔记在“自定义字段”中添加类型为 Hidden 的字段,值填入密钥;务必勾选“主密码重新提示”
证件扫描件/配置文件任意条目使用附件功能上传(默认提供 1 GB 空间)

“隐藏自定义字段”是关键

Vaultwarden 身份类型里的证件号字段默认是明文可见的。对于真正需要保护的核心秘密(API Key、证件原文),正确做法是:

  1. 创建一个“身份”或“安全笔记”条目;
  2. 滚动到 Custom Fields,类型选择 Hidden,命名(如 ID_PASSPORT 或 API_KEY_OPENAI),填入值;
  3. 勾选 “Master password re-prompt”——这样即使密码库已解锁,查看或复制这个隐藏字段时仍需再次输入主密码。

组织建议

使用 [标签] 名称 的命名方式,便于检索和隔离,例如:

  • [ID] 护照 - 中国
  • [BANK] 招商银行 - 尾号1234
  • [API] OpenAI - 项目A
  • [TOKEN] GitHub - PAT

文件夹可按 03_身份信息、04_基础设施/网络、01_财务/支付 等前缀分类。先完成这一层的结构设计,再开始录入,后续迁移会省很多整理工作。


六、迁移步骤:从 Chrome、Trilium、mindwtr 剥离

从 Chrome 剥离

  1. 在 Chrome 中访问 chrome://settings/passwords,导出密码为 CSV 文件;
  2. 登录 Vaultwarden Web 库,点击 工具 → 导入数据,格式选择 Chrome (CSV),上传文件导入;
  3. 导入完成后立即删除 CSV 文件,因为 CSV 中所有密码都是明文;
  4. 在 Chrome 设置中清除内置密码库,并将默认密码管理器切换为 Bitwarden 扩展。

从 Trilium 和 mindwtr 剥离

不要尝试从笔记中自动导出再导入。你的敏感条目数量不会太大,手工录入反而更可控,避免格式错乱和字段丢失。建议的顺序是:

  1. 先在 Vaultwarden 中建好文件夹和命名结构;
  2. 逐条将 mindwtr 任务描述中的账号/卡号/API Key 迁入对应条目;
  3. 逐条将 Trilium 私有笔记中的敏感信息迁入;
  4. 迁完后,删除原位置(mindwtr 任务描述中的文本、Trilium 中的对应笔记段落),确保敏感信息不再残留在非专用工具中。

七、运维注意事项(针对你的 1 GB 环境)

内存监控:部署后运行 docker stats vaultwarden 观察一段时间。Vaultwarden 正常占用应在 50 MB 上下,128 MB 的限制绰绰有余。如果某天出现接近上限的情况,优先排查是否有异常的大量附件上传或数据库膨胀。

可用性权衡:Vaultwarden 是你的“钥匙库”,服务器宕机时你将无法取用任何密码。建议在手机 App 中保持离线缓存开启,服务端不可达时仍可查看已同步的条目。同时,不要把云控制台或 NAS 管理密码只存在这个库里——万一需要登录服务器排障,会陷入死锁。

定期更新:固定版本号(如 1.37.5)可以避免意外升级引入问题。每隔一段时间手动将镜像版本号向前推进,更新前先备份 data 目录。

主密码的物理备份:这是整套方案中唯一无法由技术手段兜底的环节。主密码丢失 = 数据永久丢失。把它写下来,放在一个与服务器物理隔离的安全位置。


这套方案在你现有环境中的增量成本很低:一个约 50 MB 内存的容器、一个 Nginx server 块、一次 CSV 导入和一轮手工录入。换来的是凭据从 Google、Trilium 笔记、mindwtr 任务描述中彻底剥离,统一进入一个端到端加密、只有你的主密码能解锁的私有保险库,并且在 Chrome、安卓和 PC 三端都能正常自动填充。