欢迎光临

VPS自建密码管理器:Vaultwarden部署与安全加固实战指南

VPS密码管理器安全部署

为什么要在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已准备好以下条件:

  • 一个域名(如
    1
    vault.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

关键环境变量说明:

  • 1
    DOMAIN

    ——必须设置为你的实际访问地址,影响WebSocket和邮件链接

  • 1
    SIGNUPS_ALLOWED

    ——建议注册完成后改为

    1
    false

    ,防止他人注册

  • 1
    SIGNUPS_VERIFY

    ——开启邮箱验证注册

  • 1
    ADMIN_TOKEN

    ——管理面板的认证令牌,务必使用强密码

  • 1
    SHOW_PASSWORD_HINT

    ——务必设为false,密码提示是重大安全隐患

  • 1
    PUSH_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」改为
    1
    https://vault.example.com
  • 使用你注册的邮箱和主密码登录

登录后,所有密码保存、自动填充、生成器功能与Bitwarden官方服务完全一致。

移动端App

iOS和Android的Bitwarden官方App同样支持自托管:

  • 安装Bitwarden App
  • 在登录界面点击「设置」
  • 填写自托管服务器URL:
    1
    https://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端口:
    1
    ufw 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分钟,但带来的安全收益和掌控感是任何商业服务都无法替代的。从今天开始,把密码的控制权真正握在自己手中。

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » VPS自建密码管理器:Vaultwarden部署与安全加固实战指南
分享到: 更多 (0)