密码管理是企业 / 个人最值得投资的安全基础设施之一。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):
| 维度 | 官方 Bitwarden | Vaultwarden |
|---|
| 镜像大小 | ~ 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:禁止注册——第一次部署时自己注册后改 falseWEB_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_TOKEN 用 openssl 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 不支持 Upgradeproxy_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
|
首次部署流程:
- 启动 → 访问
https://vw.example.com/#/register - 注册一个管理员账户(比如
admin@example.com) - 立刻改
SIGNUPS_ALLOWED=false,重启 - 用该账户登录 → 邀请团队成员
- 强制全员开 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 客户端 GA,CLI 工具完善,企业级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 三足鼎立
下一步