部署自己的密码库 Vaultwarden

之前一直在寻找一个支持跨平台的密码管理工具,先后尝试了 1Password 和 LastPass,但是迫于贫穷,切换到了开源的 Bitwarden。后来发现了它的另一个实现 Vaultwarden(原名 Bitwarden_rs),可以很方便的使用 Docker 自己部署,同时支持了高级版的 TOTP 等功能。

下面简单记录一下部署的流程,以及部分安全设置,如自动备份等。

Vaultwarden 部署

首先安装 Docker 与 Docker Compose,参考这里

新建 docker-compose.yml 配置文件,参考下面填写,注意 DOMAIN 填入自己的实际域名。

version: '3.4'

services:

  vaultwarden:
    image: vaultwarden/server:latest
    restart: always
    ports:
      - '8080:80'
    volumes:
      - /vw-data/:/data/
    environment:
      DOMAIN: <Your Domain>
      SIGNUPS_ALLOWED: true

之后进入该目录下启动即可。

docker-compose up -d

cloudflare 证书

为了方便起见,这里直接使用了 cloudflare 代理域名,同时可以前往 SSL/TLS -> 源服务器下载其生成的主机证书,用来加密 cloudflare 与主机间的通讯。

将私钥与公钥分别保存在 /etc/nginx/ssl/cloudflare.key/etc/nginx/ssl/cloudflare.pem

nginx 配置

下面给出 nginx 的配置参考。

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

    # SSL
    ssl_certificate     /etc/nginx/ssl/cloudflare.pem;
    ssl_certificate_key /etc/nginx/ssl/cloudflare.key;

    # restrict methods
    if ($request_method !~ ^(GET|POST|PUT|DELETE)$) {
        return '403';
    }

    # Allow large attachments
    client_max_body_size 128M;

    # only allow cloudflare ip
    include /etc/nginx/cfip.conf;
    deny all;

    # logging
    access_log /var/log/nginx/vw.access.log;
    error_log  /var/log/nginx/vw.error.log warn;

    # reverse proxy
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version                 1.1;
        proxy_cache_bypass                 $http_upgrade;

        # Proxy headers
        proxy_set_header Upgrade           $http_upgrade;
        proxy_set_header Connection        $connection_upgrade;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header Forwarded         $proxy_add_forwarded;
        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;

        # Proxy timeouts
        proxy_connect_timeout              60s;
        proxy_send_timeout                 60s;
        proxy_read_timeout                 60s;
    }

    # gzip
    gzip            on;
    gzip_vary       on;
    gzip_proxied    any;
    gzip_comp_level 6;
    gzip_types      text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
}

为了安全,这里使用 cloudflare 进行代理,同时限制只允许 cloudflare 的 ip 访问,配置文件如下 /etc/nginx/cfip.conf

# https://www.cloudflare.com/ips
# IPv4
allow 173.245.48.0/20;
allow 103.21.244.0/22;
allow 103.22.200.0/22;
allow 103.31.4.0/22;
allow 141.101.64.0/18;
allow 108.162.192.0/18;
allow 190.93.240.0/20;
allow 188.114.96.0/20;
allow 197.234.240.0/22;
allow 198.41.128.0/17;
allow 162.158.0.0/15;
allow 104.16.0.0/13;
allow 104.24.0.0/14;
allow 172.64.0.0/13;
allow 131.0.72.0/22;

# IPv6
allow 2400:cb00::/32;
allow 2405:8100::/32;
allow 2405:b500::/32;
allow 2606:4700::/32;
allow 2803:f800::/32;
allow 2c0f:f248::/32;
allow 2a06:98c0::/29;

检查配置无误后重启 nginx 即可。

nginx -t
systemctl restart nginx

一切正常的话此时已经可以访问 https://vw.example.com,注册一个自己的账户并记住密码

自动备份

使用 vaultwarden-backup 实现自动备份数据。

首先配置 rclone,即配置网盘的 Token。

docker run --rm -it \
  --mount type=volume,source=vaultwarden-rclone-data,target=/config/ \
  ttionya/vaultwarden-backup:latest \
  rclone config

之后验证 rclone 配置

docker run --rm -it \
  --mount type=volume,source=vaultwarden-rclone-data,target=/config/ \
  ttionya/vaultwarden-backup:latest \
  rclone config show

# Microsoft Onedrive Example
# [YouRemoteName]
# type = onedrive
# token = {"access_token":"access token","token_type":"token type","refresh_token":"refresh token","expiry":"expiry time"}
# drive_id = driveid
# drive_type = personal

编辑上面的 docker-compose.yml,加入自动备份,注意将里面的 RCLONE_REMOTE_NAME 替换为上面配置 rclone 时填入的名字。同时这里关闭了新用户注册。

version: '3.4'

services:

  vaultwarden:
    image: vaultwarden/server:latest
    restart: always
    ports:
      - '8080:80'
    volumes:
      - /vw-data/:/data/
    environment:
      DOMAIN: <Your Domain>
      SIGNUPS_ALLOWED: false

  backup:
    image: ttionya/vaultwarden-backup:latest
    restart: always
    environment:
      RCLONE_REMOTE_NAME: 'YouRemoteName'
      CRON: '0 2 * * *'
      BACKUP_KEEP_DAYS: 10
    volumes:
      - /vw-data/:/bitwarden/data/
      - vaultwarden-rclone-data:/config/

volumes:
  vaultwarden-rclone-data:
    external: true
    name: vaultwarden-rclone-data

此外还可以配置自动发送邮件等,具体可前往这里查看。

重新启动 Docker Compose 即可

docker-compose down
docker-compose up -d

参考