为什么要在VPS上自建密码管理器?
在数字化时代,每个人平均需要管理80-120个在线账户密码。使用同一个密码、浏览器自动保存、或者记在笔记本上——这些做法都存在严重的安全隐患。商业密码管理器如1Password、Bitwarden官方版虽然好用,但年费不低,且数据存储在第三方服务器上,存在隐私泄露和供应商锁定的风险。
自建密码管理器的核心优势在于:
- 数据自主可控——所有密码数据存储在你自己的VPS上,不受第三方审查或数据泄露影响
- 零年费成本——VPS本身已有,Vaultwarden完全免费开源
- 完整功能——兼容Bitwarden客户端,支持TOTP、组织、附件等高级功能
- 性能优异——Vaultwarden用Rust编写,内存占用仅20-50MB,远低于Bitwarden官方版的2GB+
- 全球同步——手机、平板、浏览器插件均可实时同步
Vaultwarden(原名bitwarden_rs)是Bitwarden服务端的轻量级Rust实现,API完全兼容Bitwarden客户端,意味着你可以直接使用Bitwarden官方的浏览器插件、移动App和桌面客户端连接自建服务器。这是目前VPS自建密码管理器的最佳选择。
环境准备与系统要求
硬件与系统要求
Vaultwarden对资源需求极低,以下是最小和推荐配置:
| 项目 | 最低配置 | 推荐配置 |
|---|---|---|
| CPU | 1核 | 1核+ |
| 内存 | 512MB | 1GB+ |
| 磁盘 | 5GB | 10GB+ |
| 系统 | Ubuntu 20.04+ | Ubuntu 22.04/24.04 LTS |
前置条件
在开始部署前,确保你的VPS已准备好以下条件:
- 一个域名(如
1vault.example.com
)已解析到VPS的IP地址
- Docker 和 Docker Compose 已安装
- 80/443端口可用(或可通过反向代理访问)
- SSH以root或sudo权限登录
如果你尚未安装Docker,执行以下命令快速安装:
1
2
3
4
5
6
7
8
9 # 安装Docker
curl -fsSL https://get.docker.com | sh
# 启动并设置开机自启
systemctl enable --now docker
# 验证安装
docker --version
docker compose version
Vaultwarden部署实战
创建项目目录与配置文件
首先创建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 # 创建项目目录
mkdir -p /opt/vaultwarden/data
cd /opt/vaultwarden
# 创建docker-compose.yml
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: always
environment:
- DOMAIN=https://vault.example.com
- SMTP_HOST=smtp.gmail.com
- SMTP_FROM=your-email@gmail.com
- SMTP_PORT=587
- SMTP_SECURITY=starttls
- SMTP_USERNAME=your-email@gmail.com
- SMTP_PASSWORD=your-app-password
- INVITATION_ORG_NAME=MyVault
- SHOW_PASSWORD_HINT=false
- SIGNUPS_ALLOWED=true
- SIGNUPS_VERIFY=true
- WEB_VAULT_ENABLED=true
- ADMIN_TOKEN=REPLACE_WITH_HASH
- PUSH_ENABLED=true
- PUSH_INSTALLATION_ID=${PUSH_ID}
- PUSH_INSTALLATION_KEY=${PUSH_KEY}
volumes:
- ./data:/data
ports:
- "127.0.0.1:8080:80"
volumes:
data:
EOF
关键环境变量说明:
-
1DOMAIN
——必须设置为你的实际访问地址,影响WebSocket和邮件链接
-
1SIGNUPS_ALLOWED
——建议注册完成后改为
1false,防止他人注册
-
1SIGNUPS_VERIFY
——开启邮箱验证注册
-
1ADMIN_TOKEN
——管理面板的认证令牌,务必使用强密码
-
1SHOW_PASSWORD_HINT
——务必设为false,密码提示是重大安全隐患
-
1PUSH_ENABLED
——开启推送通知,实现跨设备实时同步
生成安全令牌
ADMIN_TOKEN必须使用强随机字符串。Vaultwarden 1.29+要求使用Argon2哈希格式:
1
2
3
4
5
6
7
8
9 # 生成随机ADMIN_TOKEN(Argon2哈希)
docker run --rm -it vaultwarden/server:latest /vaultwarden hash
# 输出类似 Argon2 哈希字符串,将其存入.env文件
cat > /opt/vaultwarden/.env << EOF
ADMIN_TOKEN=填入上面生成的哈希值
PUSH_ID=填入你的installation_id
PUSH_KEY=填入你的installation_key
EOF
推送通知功能需要Bitwarden官方的推送凭据。访问 Bitwarden官方推送页面,填写你的自建服务器域名即可免费获取installation_id和installation_key。
启动Vaultwarden
1
2
3
4
5
6
7
8 cd /opt/vaultwarden
# 启动服务
docker compose up -d
# 查看运行状态
docker compose ps
docker compose logs -f --tail=50
启动成功后,Vaultwarden会在
1 | 127.0.0.1:8080 |
监听。注意我们将端口绑定到localhost,不直接暴露到公网,而是通过Nginx反向代理来提供HTTPS访问。
Nginx反向代理与HTTPS配置
为什么需要反向代理?
密码管理器必须通过HTTPS传输数据。直接暴露HTTP是严重的安全风险——中间人攻击可以截获你的所有密码。Nginx反向代理负责:
- SSL/TLS终止——提供HTTPS加密
- WebSocket代理——支持Vaultwarden的实时同步
- 安全头注入——HSTS、CSP等安全策略
- 访问控制——限流、IP白名单等
安装Nginx与Certbot
1
2
3
4
5
6
7
8 # 安装Nginx
apt update && apt install -y nginx
# 安装Certbot(Let's Encrypt证书工具)
apt install -y certbot python3-certbot-nginx
# 确保Nginx运行
systemctl enable --now nginx
配置Nginx站点
创建Vaultwarden的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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 cat > /etc/nginx/sites-available/vault.example.com << 'NGINX'
server {
listen 80;
server_name vault.example.com;
# Let's Encrypt验证
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name vault.example.com;
# SSL证书(Certbot会自动填充)
ssl_certificate /etc/letsencrypt/live/vault.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/vault.example.com/privkey.pem;
# SSL安全配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
# 安全头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "no-referrer" always;
# 限流防止暴力破解
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
client_max_body_size 525M;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
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;
}
# 登录接口限流
location /identity/connect/token {
limit_req zone=login burst=3 nodelay;
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
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;
}
# 管理面板(可选择性限制IP)
location /admin {
# allow 你的IP地址;
# deny all;
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
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;
}
}
NGINX
# 启用站点配置
ln -sf /etc/nginx/sites-available/vault.example.com /etc/nginx/sites-enabled/
# 检查配置语法
nginx -t
申请Let’s Encrypt证书
1
2
3
4
5
6 # 确保DNS已解析到VPS IP
# 申请证书
certbot --nginx -d vault.example.com --non-interactive --agree-tos -m your-email@example.com
# 证书会自动续期,验证续期定时器
systemctl list-timers | grep certbot
证书申请成功后,Nginx会自动重载配置。现在可以通过
1 | https://vault.example.com |
访问Vaultwarden的Web界面了。
安全加固:从可用到生产级
关闭开放注册
这是最关键的安全措施。在你完成自己的账户注册后,立即关闭注册:
1
2
3
4
5 # 编辑docker-compose.yml,将SIGNUPS_ALLOWED改为false
sed -i 's/SIGNUPS_ALLOWED=true/SIGNUPS_ALLOWED=false/' /opt/vaultwarden/docker-compose.yml
# 重启生效
cd /opt/vaultwarden && docker compose up -d
如果未来需要邀请家人或团队成员,可以通过管理面板(
1 | /admin |
)发送邀请链接,无需开放注册。
配置Fail2Ban防暴力破解
即使有登录限流,安装Fail2Ban仍能提供额外保护层:
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 # 安装Fail2Ban
apt install -y fail2ban
# 创建Vaultwarden过滤器
cat > /etc/fail2ban/filter.d/vaultwarden.conf << 'EOF'
[INCLUDES]
before = common.conf
[Definition]
failregex = ^.*Username or password is incorrect\. Try again\. Ip address: <HOST>
ignoreregex =
EOF
# 创建Vaultwarden监狱配置
cat > /etc/fail2ban/jail.d/vaultwarden.conf << 'EOF'
[vaultwarden]
enabled = true
port = https
filter = vaultwarden
logpath = /opt/vaultwarden/data/vaultwarden.log
maxretry = 5
bantime = 3600
findtime = 600
EOF
# 在docker-compose.yml中添加日志输出
# 在environment部分添加:
# - LOG_FILE=/data/vaultwarden.log
# - LOG_LEVEL=warn
# 启动Fail2Ban
systemctl enable --now fail2ban
# 查看封禁状态
fail2ban-client status vaultwarden
数据库备份策略
Vaultwarden使用SQLite数据库,备份非常简单。创建自动备份脚本:
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 cat > /opt/vaultwarden/backup.sh << 'SCRIPT'
#!/bin/bash
set -euo pipefail
BACKUP_DIR="/opt/vaultwarden/backups"
DATA_DIR="/opt/vaultwarden/data"
RETAIN_DAYS=30
mkdir -p "$BACKUP_DIR"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/vaultwarden_$TIMESTAMP.tar.gz"
# 创建数据库快照(SQLite安全备份)
docker exec vaultwarden sqlite3 /data/db.sqlite3 ".backup /data/db-backup.sqlite3"
# 打包所有数据
tar czf "$BACKUP_FILE" -C "$DATA_DIR" db-backup.sqlite3 attachments/ sends/ rsa_key* 2>/dev/null || true
# 清理旧备份
find "$BACKUP_DIR" -name "vaultwarden_*.tar.gz" -mtime +$RETAIN_DAYS -delete
echo "[$(date)] Backup completed: $BACKUP_FILE"
SCRIPT
chmod +x /opt/vaultwarden/backup.sh
# 添加定时任务:每天凌晨3点备份
(crontab -l 2>/dev/null; echo '0 3 * * * /opt/vaultwarden/backup.sh >> /opt/vaultwarden/backup.log 2>&1') | crontab -
如果你有多台VPS或本地NAS,还可以添加异地备份。使用rsync将备份文件同步到远程存储:
1
2 # 在backup.sh末尾添加异地备份
rsync -avz --delete "$BACKUP_DIR/" user@backup-server:/backups/vaultwarden/
客户端配置与使用
浏览器插件
Vaultwarden完全兼容Bitwarden官方客户端。以Chrome浏览器插件为例:
- 从Chrome应用商店安装Bitwarden插件
- 点击插件图标 → 设置(齿轮图标)
- 将「自托管环境服务器URL」改为
1https://vault.example.com
- 使用你注册的邮箱和主密码登录
登录后,所有密码保存、自动填充、生成器功能与Bitwarden官方服务完全一致。
移动端App
iOS和Android的Bitwarden官方App同样支持自托管:
- 安装Bitwarden App
- 在登录界面点击「设置」
- 填写自托管服务器URL:
1https://vault.example.com
- 保存后登录即可
开启推送通知后,在一台设备上修改密码,其他设备会立即收到同步通知,无需手动刷新。
高级功能启用
Vaultwarden支持Bitwarden的多数高级功能:
| 功能 | 配置项 | 说明 |
|---|---|---|
| TOTP验证码 | 默认启用 | 替代Google Authenticator等独立App |
| 组织共享 | ORG_ATTACHMENT_LIMIT | 团队/家庭密码安全共享 |
| 紧急访问 | EMERGENCY_ACCESS_ALLOWED | 指定信任联系人在超时后可访问保险库 |
| Send功能 | SENDS_ALLOWED | 安全地一次性分享文本或文件 |
| 密码审计 | 默认启用 | 检测弱密码、重复密码、被泄露密码 |
运维监控与故障排查
健康检查脚本
创建一个简单的健康检查脚本,配合cron实现自动监控:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 cat > /opt/vaultwarden/healthcheck.sh << 'SCRIPT'
#!/bin/bash
set -euo pipefail
URL="https://vault.example.com/alive"
ALERT_EMAIL="your-email@example.com"
RESPONSE=$(curl -sf -o /dev/null -w "%{http_code}" "$URL" 2>/dev/null || echo "000")
if [ "$RESPONSE" != "200" ]; then
echo "[$(date)] ALERT: Vaultwarden down (HTTP $RESPONSE)" | mail -s "Vaultwarden Down!" "$ALERT_EMAIL"
# 尝试自动重启
cd /opt/vaultwarden && docker compose restart
echo "[$(date)] Restarted Vaultwarden"
fi
SCRIPT
chmod +x /opt/vaultwarden/healthcheck.sh
# 每5分钟检查一次
(crontab -l 2>/dev/null; echo '*/5 * * * * /opt/vaultwarden/healthcheck.sh >> /opt/vaultwarden/healthcheck.log 2>&1') | crontab -
常见问题排查
问题1:无法登录,提示「无法连接到服务器」
- 检查Nginx配置中proxy_set_header是否包含X-Forwarded-Proto
- 确认DOMAIN环境变量使用https://前缀
- 检查防火墙是否放行443端口:
1ufw status
问题2:WebSocket连接失败,同步延迟
- 确保Nginx配置包含Upgrade和Connection “upgrade”头
- Vaultwarden 1.29+已改为轮询方式,WebSocket不再是必需
- 开启PUSH_ENABLED使用Bitwarden推送服务替代
问题3:证书续期失败
1
2
3
4
5
6
7
8 # 手动测试续期
certbot renew --dry-run
# 检查续期定时器状态
systemctl list-timers | grep certbot
# 如果certbot定时器不存在,手动创建
(crontab -l 2>/dev/null; echo '0 0 * * 0 certbot renew --quiet --post-hook "systemctl reload nginx"') | crontab -
问题4:Docker容器反复重启
1
2
3
4
5
6
7
8 # 查看详细日志
docker compose logs --tail=100
# 常见原因:
# - .env文件中ADMIN_TOKEN格式错误
# - 端口被占用
# - 数据目录权限问题
ls -la /opt/vaultwarden/data/
升级与维护
Vaultwarden持续活跃开发,定期升级能获取安全修复和新功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 # 升级流程
cd /opt/vaultwarden
# 1. 备份
docker exec vaultwarden sqlite3 /data/db.sqlite3 ".backup /data/db-backup.sqlite3"
# 2. 拉取最新镜像
docker compose pull
# 3. 重启服务(自动使用新镜像)
docker compose up -d
# 4. 验证
docker compose ps
curl -sf https://vault.example.com/alive
# 5. 清理旧镜像
docker image prune -f
建议在升级前查看 Vaultwarden Release页面,了解是否有破坏性变更。大部分小版本升级可以直接升级,大版本升级可能需要数据库迁移。
安全最佳实践总结
部署密码管理器本身就是安全意识的体现,但若配置不当反而会制造新的风险点。以下是一份安全清单,请逐项确认:
| 类别 | 检查项 | 状态 |
|---|---|---|
| 传输安全 | 强制HTTPS(HSTS头) | 必须 |
| 传输安全 | TLS 1.2+协议 | 必须 |
| 认证安全 | 关闭开放注册 | 必须 |
| 认证安全 | ADMIN_TOKEN使用Argon2哈希 | 必须 |
| 认证安全 | 关闭密码提示显示 | 必须 |
| 暴力防护 | Nginx登录限流 | 强烈建议 |
| 暴力防护 | Fail2Ban封禁 | 强烈建议 |
| 数据安全 | 每日自动备份 | 强烈建议 |
| 数据安全 | 异地备份 | 建议 |
| 运维安全 | 管理面板IP限制 | 建议 |
| 运维安全 | 健康检查与自动重启 | 建议 |
| 账户安全 | 主密码强度14位以上 | 必须 |
| 账户安全 | 启用TOTP两步验证 | 强烈建议 |
最后提醒:你的主密码是整个密码管理器安全的最后一道防线。Vaultwarden采用端到端加密,即使服务器被攻破,攻击者没有主密码也无法读取你的密码数据。请务必使用至少14位的强主密码,并启用TOTP两步验证。
自建密码管理器并不是一件复杂的事情——整个部署过程不超过30分钟,但带来的安全收益和掌控感是任何商业服务都无法替代的。从今天开始,把密码的控制权真正握在自己手中。
汤不热吧