Featured image of post Vaultwarden 密码管理自托管:Bitwarden 兼容 + WebSocket + Nginx 反代

Vaultwarden 密码管理自托管:Bitwarden 兼容 + WebSocket + Nginx 反代

用 Vaultwarden 替代 Bitwarden 官方服务,自托管 5MB 镜像即可获得跨平台密码同步能力,配套 Nginx 反代与 WebSocket 通知完整配置

密码管理是企业 / 个人最值得投资的安全基础设施之一。1Password / LastPass 商业版每年几十美元 / 用户,Vaultwarden(Bitwarden 兼容)自托管只要 1 个 Docker 容器——而且数据完全掌控在自己手里。本篇把完整部署、Nginx 反代、WebSocket 通知、生产加固整理清楚。

阅读对象:技术团队负责人 / 注重个人隐私的开发者 覆盖范围:Vaultwarden 基础部署 + 完整 docker-compose + WebSocket 通知 + Nginx 反代 + 备份恢复 + 高级加固

一、为什么选 Vaultwarden

Bitwarden 是开源密码管理器,跨平台支持完善(Windows / macOS / Linux / iOS / Android / 浏览器扩展)。但官方服务端需要 SQL Server(商业版),自托管成本高。

Vaultwarden 是 Bitwarden 服务端的社区重写版(原名 bitwarden_rs):

维度官方 BitwardenVaultwarden
镜像大小~ 1.5 GB(含 SQL Server)~ 80 MB
内存占用2GB+50-100 MB
数据库SQL Server(必须)SQLite / PostgreSQL / MySQL
客户端兼容官方客户端官方客户端全兼容
API 兼容原生100% 兼容
项目维护Bitwarden Inc.社区

2021-04-27 项目从 bitwarden_rs 更名为 Vaultwarden客户端仍是 Bitwarden 官方客户端——只是服务端换成 Vaultwarden 即可。

When to use

  • 团队 / 公司有 5+ 员工,需要共享密码
  • 注重数据隐私,不想把密码交给第三方
  • 已经买了 1Password 商业版但想降本

二、基础部署

2.1 SQLite 版本(个人 / 小团队)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
docker run -d \
  --name vaultwarden \
  --restart always \
  -e WEBSOCKET_ENABLED=true \
  -e SIGNUPS_ALLOWED=false \
  -e WEB_VAULT_ENABLED=true \
  -v /home/vw/data:/data \
  -p 8087:80 \
  -p 3012:3012 \
  vaultwarden/server:1.25.1-alpine

环境变量:

  • WEBSOCKET_ENABLED=true:启用 WebSocket(密码同步通知)
  • SIGNUPS_ALLOWED=false禁止注册——第一次部署时自己注册后改 false
  • WEB_VAULT_ENABLED=true:启用 Web 客户端
  • ADMIN_TOKEN=...可选):后台管理密码

2.2 docker-compose 完整版

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
version: '3'
services:
  vaultwarden:
    image: vaultwarden/server:1.25.1-alpine
    container_name: vaultwarden
    restart: always
    environment:
      WEBSOCKET_ENABLED: "true"
      SIGNUPS_ALLOWED: "false"
      WEB_VAULT_ENABLED: "true"
      ADMIN_TOKEN: "{{REDACTED}}"   # 用 openssl rand -base64 48 生成
      ROCKET_PORT: "8087"
      DOMAIN: "https://vw.example.com"
      SHOW_PASSWORD_HINT: "false"
      LOG_LEVEL: "warn"
    volumes:
      - /home/vw/data:/data
    ports:
      - "8087:8087"
      - "3012:3012"

ADMIN_TOKENopenssl rand -base64 48 生成——这是后台管理面板 /admin 的访问密码

2.3 PostgreSQL 版本(生产推荐)

SQLite 在并发写入时容易锁库——团队 20+ 用户推荐 PostgreSQL:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
version: '3'
services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: always
    depends_on:
      - postgres
    environment:
      DATABASE_URL: postgresql://vaultwarden:{{DB_PASS}}@postgres:5432/vaultwarden
      WEBSOCKET_ENABLED: "true"
      SIGNUPS_ALLOWED: "false"
      WEB_VAULT_ENABLED: "true"
      ADMIN_TOKEN: "{{REDACTED}}"
      DOMAIN: "https://vw.example.com"
    volumes:
      - /home/vw/data:/data
    ports:
      - "8087:8087"
      - "3012:3012"

  postgres:
    image: postgres:13-alpine
    container_name: vaultwarden-db
    restart: always
    environment:
      POSTGRES_USER: vaultwarden
      POSTGRES_PASSWORD: "{{DB_PASS}}"
      POSTGRES_DB: vaultwarden
    volumes:
      - /home/vw/pgdata:/var/lib/postgresql/data

生产推荐用 PostgreSQL,性能 + 并发 + 备份工具都更成熟

三、Nginx 反向代理

直接用 :8087 端口访问不安全——必须套 HTTPS。

3.1 完整 Nginx 配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
server {
    listen 80;
    server_name vw.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name vw.example.com;

    ssl_certificate     /etc/nginx/ssl/vw.example.com.fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/vw.example.com.privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;

    # HSTS
    add_header Strict-Transport-Security "max-age=63072000" always;

    # 反代主应用
    location / {
        proxy_pass http://127.0.0.1:8087;
        proxy_http_version    1.1;
        proxy_cache_bypass    $http_upgrade;
        proxy_set_header Upgrade            $http_upgrade;
        proxy_set_header Connection         "upgrade";
        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;
        proxy_set_header X-Forwarded-Host   $host;
        proxy_set_header X-Forwarded-Port   $server_port;
    }

    # WebSocket 通知(密码同步实时推送)
    location /notifications/hub {
        proxy_pass http://127.0.0.1:3012;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    # WebSocket 协商
    location /notifications/hub/negotiate {
        proxy_pass http://127.0.0.1:8087;
    }

    # 后台管理面板
    location /admin {
        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;
        proxy_pass http://127.0.0.1:8087;
    }

    # 防止搜索引擎抓取(重要!)
    location = /robots.txt {
        root /home/wwwroot/Bitwarden;
    }
}

关键点

  • proxy_http_version 1.1:必须 1.1,HTTP/1.0 不支持 Upgrade
  • proxy_set_header Connection "upgrade":触发协议升级
  • /notifications/hub 走 3012 端口(WebSocket 专用)
  • /admin 路径在 Vaultwarden 中默认不开放——要 ADMIN_TOKEN 启用

3.2 反代安全清单

风险修复
robots.txt 让搜索引擎爬必须 配自定义 robots.txt 禁止爬取
弱密码注册时强制密码强度,禁止 123456
SIGNUPS_ALLOWED=true第一次注册后立刻改 false
暴露管理面板ADMIN_TOKEN 用 48 字节随机数,别用生日
没限流用 Nginx limit_req 防爆破
1
2
3
4
5
6
7
# 登录限流
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

location /api/auth {
    limit_req zone=login burst=3 nodelay;
    proxy_pass http://127.0.0.1:8087;
}

四、客户端使用

4.1 桌面客户端

打开 Bitwarden 桌面客户端 → 设置 → 服务器 URL → https://vw.example.com

4.2 浏览器扩展

Chrome / Edge / Firefox 商店搜 “Bitwarden” → 安装 → 设置 → 服务器 URL。

4.3 移动端

iOS / Android 装 Bitwarden 官方 App,首次登录用自托管 URL

4.4 导入已有密码

Bitwarden 支持从以下来源导入:

  • 1Password(.1pif)
  • LastPass(.csv)
  • Chrome / Firefox(.csv)
  • KeePass(.xml)
  • Dashlane / RoboForm / Enpass

Web 客户端 https://vw.example.com/#/tools/import 操作。

五、备份与恢复

5.1 SQLite 备份

1
2
3
4
5
# 在线备份(不锁库)
docker exec vaultwarden sqlite3 /data/db.sqlite3 ".backup '/data/backup/db-$(date +%Y%m%d).sqlite3'"

# 拷贝出来
docker cp vaultwarden:/data/backup ./vaultwarden_backup_$(date +%Y%m%d)

5.2 PostgreSQL 备份

1
2
3
4
5
# 逻辑备份
docker exec vaultwarden-db pg_dump -U vaultwarden vaultwarden > vw-$(date +%Y%m%d).sql

# 物理备份(推荐)
docker exec vaultwarden-db pg_basebackup -D /backup/$(date +%Y%m%d) -U vaultwarden -Fp -Xs -P

5.3 附件 / 密钥 / RSA 密钥

1
2
3
4
5
# 全量备份
tar czf vw-full-backup-$(date +%Y%m%d).tar.gz /home/vw/data

# 上传对象存储
ossutil cp vw-full-backup-*.tar.gz oss://backup-bucket/vaultwarden/

5.4 恢复

1
2
3
4
5
6
7
8
# 1. 停服
docker compose down

# 2. 恢复数据
tar xzf vw-full-backup-20240315.tar.gz -C /

# 3. 启动
docker compose up -d

自动备份到 OSS

1
2
# crontab 每天 3 点
0 3 * * * /usr/local/bin/vw_backup.sh

六、Admin 后台

启用 ADMIN_TOKEN 后访问 https://vw.example.com/admin

1
2
3
# 生成强 token
openssl rand -base64 48
# 输出:eK7vN9pQ2xR5tY8wA1bC3dF6gH0iJ4kL7mN9oP2qR5tU8vW1xY4zA7bC0dF3gH6i

后台功能:

  • 查看用户列表
  • 禁用 / 启用用户
  • 强制 2FA(团队必开)
  • 查看登录日志
  • 删除用户及其数据

强 2FA 策略

1
2
# 禁止非 2FA 用户登录(管理面板)
# 后台 → Users → 用户 → 勾选 "Require 2FA"

七、生产加固清单

7.1 网络层

  • 强制 HTTPS(Nginx 301 重定向)
  • 限流(Nginx limit_req 防爆破)
  • IP 白名单(后台 /admin 限定内网)
  • fail2ban(自动封禁多次失败 IP)

7.2 应用层

  • SIGNUPS_ALLOWED=false(注册后必关)
  • 强 ADMIN_TOKEN(48 字节随机)
  • 数据库连接加密(PostgreSQL SSL)
  • 禁用密码提示SHOW_PASSWORD_HINT=false

7.3 监控

1
2
3
4
5
6
# 接入 Loki
docker run -d \
  --name vaultwarden \
  --log-driver=loki \
  --log-opt loki-url="http://internal.example.com:3100/loki/api/v1/push" \
  ...

告警规则:

  • 失败登录 > 100/小时:可能有人在爆破
  • 新用户注册SIGNUPS_ALLOWED=false 后应为 0
  • 数据库连接失败:PostgreSQL 健康检查

八、典型坑位

8.1 WebSocket 连接 404

症状:客户端同步卡死,提示 WebSocket 失败

修复

  • WEBSOCKET_ENABLED=true 环境变量
  • 3012 端口在 Nginx 暴露:location /notifications/hub
  • proxy_http_version 1.1 + proxy_set_header Connection "upgrade"

8.2 文件上传 413

症状:上传附件 > 1MB 失败。

修复

1
client_max_body_size 100m;

8.3 团队成员密码泄露

应急

1
2
3
4
# 1. 后台 /admin 禁用该用户
# 2. 强制全员改主密码
# 3. 检查登录日志,看是否有异常 IP
docker logs vaultwarden 2>&1 | grep -E "Failed login|Invalid"

8.4 Vaultwarden 升级失败

症状:升级后数据库迁移报错。

修复

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 1. 升级前必备份
docker exec vaultwarden-db pg_dump -U vaultwarden vaultwarden > vw-backup.sql

# 2. 升级
docker compose pull vaultwarden
docker compose up -d

# 3. 启动失败时查看日志
docker logs vaultwarden

# 4. 回滚
docker compose down
docker compose up -d vaultwarden-server:1.25.0   # 回退到旧版本

九、Vaultwarden vs 其他方案

工具开源自托管跨平台团队功能2FA
Vaultwarden
1Password
LastPass
KeePass + SyncTrayzor⚠️⚠️
Bitwarden 官方⚠️

自托管 + 团队功能两个条件同时满足,Vaultwarden 是唯一靠谱的开源选择

十、完整 docker-compose 生产示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
version: '3.8'
services:
  vaultwarden:
    image: vaultwarden/server:1.30.0-alpine
    container_name: vaultwarden
    restart: always
    depends_on:
      - postgres
    environment:
      DATABASE_URL: postgresql://vaultwarden:{{DB_PASS}}@postgres:5432/vaultwarden
      WEBSOCKET_ENABLED: "true"
      SIGNUPS_ALLOWED: "false"
      WEB_VAULT_ENABLED: "true"
      ADMIN_TOKEN: "{{REDACTED}}"
      DOMAIN: "https://vw.example.com"
      SHOW_PASSWORD_HINT: "false"
      LOG_LEVEL: "warn"
      SIGNUPS_DOMAINS_WHITELIST: "example.com"  # 只允许企业邮箱注册(首次)
      INVITATIONS_ALLOWED: "true"               # 团队邀请
      DISABLE_ICON_DOWNLOAD: "true"             # 防止外网图片泄露
    volumes:
      - /home/vw/data:/data
    networks:
      - vw-net
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8087/alive"]
      interval: 30s
      timeout: 5s
      retries: 3

  postgres:
    image: postgres:15-alpine
    container_name: vaultwarden-db
    restart: always
    environment:
      POSTGRES_USER: vaultwarden
      POSTGRES_PASSWORD: "{{DB_PASS}}"
      POSTGRES_DB: vaultwarden
    volumes:
      - /home/vw/pgdata:/var/lib/postgresql/data
    networks:
      - vw-net

networks:
  vw-net:
    driver: bridge

首次部署流程

  1. 启动 → 访问 https://vw.example.com/#/register
  2. 注册一个管理员账户(比如 admin@example.com
  3. 立刻SIGNUPS_ALLOWED=false,重启
  4. 用该账户登录 → 邀请团队成员
  5. 强制全员开 2FA

2024+ 视角补充

本文写于 2023-03,2024-2026 期间 Vaultwarden 关键演进:

  • Vaultwarden 1.30+(2024-08):Passkey / WebAuthn 完整支持(vs 老版本仅 TOTP)——2024+ 无密码化趋势下的核心能力
  • Vaultwarden 1.32+(2025-Q1):内置 SSO(SAML 2.0 / OIDC)——企业 AD / Okta / Azure AD 集成开箱即用
  • Vaultwarden 1.33+(2025-Q3):Send 端到端加密文件分享(vs 老版本仅文字);风险评估报告(用户密码健康度)
  • Bitwarden 官方 2024 重构:原 Bitwarden 服务端(商业版)2024-2025 全面转向 Rust 重写,性能 3x 提升——但 Vaultwarden 仍 100% 兼容官方客户端
  • 替代品(2024+ 视角):
    • Bitwarden 官方(商业):2024 起免费版限制到 2 用户——中小企业必须付费
    • Proton Pass(2024-Q3):Proton 公司出品,E2EE 邮件 + 密码一体化——隐私党新选择
    • 1Password 8.x(2024):Linux 客户端 GACLI 工具完善,企业级SCIM 同步
    • Passwork / Psono(2024):欧洲 GDPR 友好,自托管 + 团队功能
    • KeePassXC + KeePassDX(移动)+ Syncthing 同步:纯本地方案 2024 仍活跃

实战建议(2025-2026 视角)

  • 个人 / 小团队Vaultwarden 1.33+ 仍是首选自托管方案
  • 企业 / 合规 → Vaultwarden 1.32+ 的 SSO + RBAC 满足等保 / SOC 2 基础要求
  • 无密码化 → Passkey + Vaultwarden 1.30+ 已是稳态组合
  • 云服务 → Bitwarden / 1Password / Proton Pass 三足鼎立

下一步

使用 Hugo 构建
主题 StackJimmy 设计