使用 Docker 部署私有密码管理服务 Vaultwarden

项目概述

Vaultwarden 是一个用 Rust 编写的开源密码管理服务,它是 Bitwarden 的非官方服务器实现。相比官方服务器,它具有以下优势:

  • 资源占用更少(内存占用约 10MB)
  • 部署维护更简单
  • 完全兼容官方客户端
  • 支持所有核心功能
  • 只需要记住一个主密码就能使用,但是如果忘记主密码还没有导出备份将是一场灾难

本文将详细介绍如何使用 Docker 部署 Vaultwarden,并配置必要的安全措施。

📝 环境信息

本文基于以下环境进行部署:

  • 操作系统:Ubuntu 22.04 LTS
  • Docker 版本:24.0.0 或更高
  • 域名:vault.adrainlee.me(请替换为你的实际域名)

安全性考虑

在开始部署之前,请确保考虑以下安全措施:

  1. 系统安全
  • 使用防火墙限制端口访问
  • 启用 fail2ban 防止暴力攻击
  • 定期更新系统和软件包
  1. 数据安全
  • 启用定时备份
  • 实施访问控制(如果可能)
  1. 网络安全
  • 配置 SSL/TLS 证书
  • 启用 HTTP/2
  • 实施速率限制(如果可能)

部署步骤

1. 配置 Nginx 反向代理

1.1 安装必要组件

# 更新软件包列表
sudo apt update

# 安装 Nginx
sudo apt install -y nginx

#安装 Certbot
sudo snap install --classic certbot

1.2 配置 Nginx

在开始配置nginx的作用在于,如果使用http来连接vaultwarden会有莫名其妙的错误,也毫无安全可言,可以先配置好https再运行vaultwarden容器可以平滑的使用

在/etc/nginx/sites-available目录下创建 Nginx 配置文件 vault.adrainlee.me.conf:

sudo vim /etc/nginx/sites-available/vault.adrainlee.me.conf

使用以下配置

# HTTPS 服务器
server {
    listen 80;
    server_name vault.adrainlee.me; #请修改为你的域名

    # 安全头部
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "no-referrer" always;
    add_header Content-Security-Policy "default-src 'self' https: data: 'unsafe-inline' 'unsafe-eval'" always;

    # Vaultwarden API
    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 支持
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # 超时设置
        proxy_read_timeout 1h;
        proxy_send_timeout 1h;
    }

    # WebSocket 通知
    location /notifications/hub {
        proxy_pass http://127.0.0.1:3012;
        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 Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 1h;
        proxy_send_timeout 1h;
    }

    # WebSocket 协商
    location /notifications/hub/negotiate {
        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;
    }
}

1.3 启用配置并申请证书

# 创建符号链接
sudo ln -s /etc/nginx/sites-available/vaultwarden.conf /etc/nginx/sites-enabled/

# 测试配置
sudo nginx -t

# 重启 Nginx
sudo systemctl restart nginx

#  安装certbot
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

# 申请 SSL 证书
sudo certbot --nginx -d vault.adrainlee.me

如果没有安装certbot请参考官网步骤安装 certbot官网:certbot.eff.org

2. 安装 Docker 和 Docker Compose

# 使用官方脚本一键安装 Docker & Docker Compose
curl -fsSL https://get.docker.com | bash -s docker

# 将当前用户添加到 docker 组
sudo usermod -aG docker $USER

# 应用组权限(无需重启)
newgrp docker

⚠️ 注意

从 Docker Compose V2 开始,命令已更改为 docker compose(移除了中划线)。本文使用新的命令格式。

3. 部署 Vaultwarden

3.1 创建.env文件保存ADMIN_TOKEN

echo "ADMIN_TOKEN=$(openssl rand -base64 48)" > .env

在指定目录创建, 示例中使用(/data/vaultwarden-docker) Docker Compose 配置文件:

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    ports:
      - '127.0.0.1:8080:80'
      - '127.0.0.1:3012:3012'
    volumes:
      - ./data:/data
    environment:
      # 基本配置
      - DOMAIN=https://vault.adrainlee.me
      - SIGNUPS_ALLOWED=false #禁止注册
      - ADMIN_TOKEN=${ADMIN_TOKEN} #Docker Compose 会自动读取同目录下的 .env 文件中的环境变量

      # 安全配置
      - LOGIN_RATELIMIT_MAX_BURST=10
      - LOGIN_RATELIMIT_SECONDS=60
      - ADMIN_RATELIMIT_MAX_BURST=10
      - ADMIN_RATELIMIT_SECONDS=60
      - ADMIN_SESSION_LIFETIME=20

      # 功能限制
      - SENDS_ALLOWED=false
      - EMERGENCY_ACCESS_ALLOWED=false
      - WEB_VAULT_ENABLED=true

    healthcheck:
      test: ['CMD', 'curl', '-f', 'http://localhost:80/alive']
      interval: 30s
      timeout: 10s
      retries: 3

  watchtower:
    image: containrrr/watchtower
    container_name: watchtower
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_POLL_INTERVAL=86400

Watchtower 配置说明

  • image: containrrr/watchtower:这是 Watchtower 的官方镜像。
  • volumes: /var/run/docker.sock:/var/run/docker.sock:这是 Watchtower 监控 Docker 容器所必需的挂载卷。它允许 Watchtower 与 Docker 守护进程通信。
  • WATCHTOWER_CLEANUP=true:这个环境变量告诉 Watchtower 在更新容器后自动删除旧的镜像,避免占用磁盘空间。
  • WATCHTOWER_POLL_INTERVAL=3600:这个环境变量设置 Watchtower 检查更新的频率(以秒为单位)。这里设置为 3600 秒(1 小时),你可以根据需要调整。

4. 在管理后台邀请用户

因为在compose配置文件中关闭了注册,需要手动邀请用户注册

4.1 查看 ADMIN_TOKEN

docker compose config | grep ADMIN_TOKEN
# 输出内容为ADMIN_TOKEN: XghY7AYd1SlPuNspub6VaBRt8N6CJmEzACTbWp8+Ph/d1vN02X53VuPi0R0GnMG/
# 复制冒号后的所有字符趾,不包含空格

4.2 登录管理后台

只有在配置了ADMIN_TOKEN后才会开启管理后台,地址格式为: https://域名/admin,输入TOKEN

4.2.1 配置SMTP服务器

在settings选项卡 smtp email settings中配置smtp服务器保存并测试

4.2.2 邀请用户注册

测试成功后在users选项卡输入邮箱邀请用户,用户收到邀请链接完成注册,在客户端做好配置就可以使用了

5. vaultwarden数据备份和恢复

在使用 Docker Compose 运行 Vaultwarden 容器时,定时备份密码库是非常重要的,以确保数据安全。Vaultwarden 默认使用 SQLite 数据库来存储用户数据,因此备份主要涉及备份 SQLite 数据库文件和相关附件。

5.1使用定时任务备份

创建备份脚本:

#!/bin/bash

# 配置
BACKUP_DIR="/opt/vaultwarden/backups"
RETENTION_DAYS=30
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="vaultwarden_backup_${TIMESTAMP}.tar.gz"
LOG_FILE="${BACKUP_DIR}/backup.log"

# 创建备份目录
mkdir -p "${BACKUP_DIR}"

# 备份数据
docker exec vaultwarden sqlite3 /data/db.sqlite3 ".backup '/data/db.sqlite3.backup'"
docker cp vaultwarden:/data/. "${BACKUP_DIR}/temp/"
tar czf "${BACKUP_DIR}/${BACKUP_FILE}" -C "${BACKUP_DIR}/temp" .
rm -rf "${BACKUP_DIR}/temp"

# 清理旧备份
find "${BACKUP_DIR}" -type f -name "vaultwarden_backup_*.tar.gz" -mtime +${RETENTION_DAYS} -delete

将上述脚本保存为 backup_vaultwarden.sh,并赋予执行权限:

chmod +x backup_vaultwarden.sh

使用 cron 来定时执行备份脚本。编辑 cron 任务:

crontab -e

添加以下行,表示每天凌晨 2 点执行备份脚本:

0 2 * * * /path/to/backup_vaultwarden.sh

保存并退出。cron 将每天自动执行备份脚本,并将备份文件存储在指定的目录中。

4.2 恢复备份

如果需要恢复备份,可以使用以下步骤: 停止 Vaultwarden 容器

docker-compose down

恢复备份文件,将备份文件解压到 Vaultwarden 的数据目录中:

tar xzf /path/to/backup/vaultwarden_backup_YYYYMMDD_HHMMSS.tar.gz -C /path/to/vaultwarden_data

重新启动 Vaultwarden 容器

docker-compose up -d

5. 客户端配置指南

5.1 浏览器扩展设置

在浏览器扩展中配置自托管服务器:

  • 安装 Bitwarden 浏览器扩展
  • 点击设置图标
  • 选择"自托管环境"
  • 输入服务器 URL:https://vault.adrainlee.me
  • 保存设置并登录

移动应用配置

在 Bitwarden 移动应用中配置:

  • 打开 Bitwarden 应用
  • 进入设置
  • 选择"自托管"选项
  • 输入服务器 URL
  • 保存并重新登录

6. 维护和监控

6.1 健康检查

# 检查容器状态
docker ps -a | grep vaultwarden

# 查看日志
docker logs -f vaultwarden

# 检查资源使用
docker stats vaultwarden

6.2 更新管理

Watchtower 会自动检查并更新容器。你也可以手动更新:

# 拉取最新镜像
docker pull vaultwarden/server:latest

# 重启容器
docker-compose down
docker-compose up -d

故障排除

常见问题解决

  1. 连接问题
  • 检查 Nginx 配置
  • 验证 SSL 证书
  • 确认防火墙规则
  1. 性能问题
  • 监控资源使用
  • 优化数据库
  • 清理日志文件
  1. 备份恢复
  • 定期测试备份
  • 验证备份完整性
  • 建立恢复流程

总结

通过本文的介绍,你已经搭建了一个相对安全、可靠的私有密码管理服务。记得定期检查系统更新、备份数据,并保持良好的安全实践。