使用Docker Compose及Nginx配置Vaultwraden

我之前一直是使用keepass作为密码管理器,再加上Dropbox作为同步的工具,如果是纯桌面端的话,这样配合使用体验很不错,基本上能满足我日常的密码使用需求,但是因为众所周知的原因Dropbox在国内网络下并不能直接连接,再加上Keepass在iOS系统上并没有比较好用的客户端,随着手机上各种App的账号密码数量的增加,单纯靠脑子已经无法记住那么多的密码了。恰巧更新iOS15之后,发现可以使用Bitwarden接替iOS系统自带的钥匙串的密码管理功能,于是研究了下,发现自建Bitwarden服务端的情况下,能比较方便在各端同步各类密码,这里记录下我的配置过程。

Vaultwarden及Bitwarden介绍

Bitwarden是一款开源的密码管理器,其提供多种操作系统的客户端,包括Windows、macOS、Android以及iOS等,官方提供付费的密码托管服务,同时也提供服务端程序用于用户自行部署服务,但是官方提供的服务端程序比较占用资源,而Vaultwarden是根据官方提供的服务端程序非官方开源程序,相比原版的Bitwarden服务端,Vaultwarden使用Rust编写,且使用小巧的SQLite代替比较占资源的MSSQL,且Vaultwarden官方提供Docker镜像,我们自行部署的话,只需要拉取官方提供的Docker镜像即可。

PS:Vaultwarden由Bitwarden_rs更名而来,据作者说,是为了避免与Bitwarden官方相混淆,所以更名为Vaultwarden。

所需资源及配置目的

自行部署的话,需要有一台能运行Docker的服务器,以及一个域名,我使用的是腾讯云轻量云服务器,系统为Debian11,SSL证书是腾讯云提供的免费的TrustAsia,实测Vaultwarden占用的内存很少,同一台服务器上除了使用Docker运行的Vaultwarden外,加上Nginx、PHP7.4、MariaDB以及多个WordPress网站一起都才占用500MB不到,1G内存的服务器都绰绰有余了。

我的目的是在这台腾讯云的轻量云服务器上运行一个可以长期在多端且随时随地都能访问的Vaultwarden密码服务,为了服务器不至于太凌乱,Vaultwarden服务能与其他服务在同一个域名下共存。

配置过程

下面是我的详细配置过程。

安装Docker、docker-compose及Nginx

我是用的是Debian11,安装Docker命令如下:

apt-get update

apt-get install apt-transport-https ca-certificates curl gnupg lsb-release

curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian  $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

apt-get update

apt-get install docker-ce docker-ce-cli containerd.io

docker-compose下载页面:

https://github.com/docker/compose/releases/

从上面下载最新的release就行,比如我目前最新的正式版release:

wget https://github.com/docker/compose/releases/download/v2.1.1/docker-compose-linux-x86_64
chmod +x docker-compose-linux-x86_64
mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose

至于Nginx,其实很简单,一行命令即可,如果已安装可以跳过:

apt install nginx

docker-compose.yml配置

随便选择一个目录,用来放置Vaultwarden的yml及对应的数据文件,比如说/var/www/vaultwarden,然后输入如下配置:

vim docker-compose.yml

version: "3"

services:
  vaultwarden:
    image: vaultwarden/server
    container_name: vaultwarden
    restart: always
    ports:
        - "127.0.0.1:8081:80"
        - "127.0.0.1:3012:3012"
    volumes:
      - ./vw-data:/data
    environment:
      WEBSOCKET_ENABLED: "true"
      SIGNUPS_ALLOWED: "true"
      WEB_VAULT_ENABLED: "true"
      DOMAIN: "https://cloudbool.com/archive/vault"

其中SIGNUPS_ALLOWED是配置是否允许注册,建议第一次使用的时候开启,待我们自己注册完了可以设置成false以禁止再次注册;WEB_VAULT_ENABLED是配置是否开启Web端访问,需要Web端访问的可以选择true,否则可以选择false。

因为我是打算将Vaultwarden与其他应用配置到同一个域名下面,所以需要上述的environment下面的DOMAIN变量,如果是独立一个域名用来配置Vaultwarden,可以不需要DOMAIN这项配置。

Nginx配置

上面说了,我是打算将Vaultwarden与别的服务公用一个域名,所以对应的Nginx配置如下:

server{
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name  cloudbool.com;
        index index.php;
        root /www/cloudbool/;
        ssl_certificate /ssl/cloudbool-rsa.crt;
        ssl_certificate_key /ssl/cloudbool-rsa.key;
        ssl_session_cache        shared:SSL:10m;
        ssl_session_timeout      10m;
        ssl_session_tickets      on;
        resolver                 119.29.29.29  valid=300s;
        resolver_timeout         10s;
        ssl_session_cache builtin:1000 shared:SSL:10m;
        ssl_dhparam /ssl/dhparam.pem;
        ssl_prefer_server_ciphers on;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;

        location / {
                ...
        }

        location /vault/ {
                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:8080;
        }

        location /vault/notifications/hub/negotiate {
                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:8080;
        }

        location /vault/notifications/hub {
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection $http_connection;
                proxy_set_header X-Real-IP $remote_addr;

                proxy_pass http://127.0.0.1:3012;
        }

}

server
{
        listen          80;
        server_name cloudbool.com;
        location / {
                rewrite ^/(.*)$ https://cloudbool.com/archive/$1 permanent;
        }
}

如果是打算使用单独的域名配置Vaultwarden,可以不需要上述目录匹配的/vault部分。

启动Vaultwarden

因为我是使用的docker-compose来管理Vaultwarden,启动和关闭的命令很简单:

# 启动
docker-compose up -d
# 重启
docker-compose restart
# 停止
docker-compose down
# 更新vaultwarden镜像,需要先停止
docker pull vaultwarden/server:latest

如果没有问题的话,可以直接使用上述Nginx配置的域名加目录进行访问了,比如我这里配置的就是:https://cloudbool.com/archive/vault/

客户端配置

第一次使用的时候,可以在Web端注册一个账号,访问上述域名即可,客户端使用的时候,在软件启动之后,将托管URL设置成上述域名即可,注意如果配置了独立的目录则需要将目录也带上。

vaultwarden数据备份

如果跟我一样,选择将vaultwarden的数据放在/var/www/vaultwarden,则所有数据都在该目录下面,备份的时候将里面所有的文件或者挣个文件夹备份就行,如果不放心,还可以单独将里面的sqlite3数据备份一下,例如将文件备份至~:

sqlite3 /var/www/vaultwarden/bw-data/db.sqlite3 ".backup '/root/db-$(date '+%Y%m%d-%H%M').sqlite3'"

如果提示“-bash: sqlit3: command not found”,则手动安装一下sqlite3就行:

apt install sqlite3