12 min read

VaultWarden: 私有 Bitwarden 密码管理器服务端部署指南

VaultWarden: 私有 Bitwarden 密码管理器服务端部署指南

Bitwarden 是一款开源的密码管理器,具有完善的跨平台支持,可以轻松的在手机和电脑上访问和使用。它的所有源代码均托管在 Github 仓库,任何人都可以随时获取、查看和评估其代码。这也意味着,除了使用官方的云服务,你也可以自己部署私有的 Bitwarden 服务器来保存密码。

1. 你真的需要私有化部署吗?

在开始之前,你需要了解的第一个问题并不是“如何部署 Bitwarden 服务器?“,而是要先问问自己是否有必要进行私有化部署?因为 Bitwarden 官方服务非常方便,提供的免费版服务对大多数用户来说已经够用,下载注册即可使用,没有设备数限制,也没有密码条数限制。即便是为了获得更多高级功能升级成为付费用户,每月的花费折合人民币也不过几块钱而已。

下图截取自 2023 年 2 月 Bitwarden 官网对个人和家庭用户的报价:

2023 年 Bitwarden 面向个人用户的报价
  • 永久免费版:包含全部基本功能,适用于大多数用户;
  • 高级版:年付 $10 美元,除基本功能外还包括 2FA 认证、紧急访问等高级功能;
  • 家庭版:月付 $3.33 美元,年付 $40 美元。包含 6 个高级版用户,以及家庭功能功能等。

部署私有的 Bitwarden 服务端就是不再保存密码到 Bitwarden 官方的服务器,而是在自己的服务器上创建账号和保存密码,由你自己完全掌控密码数据库,解锁所有高级功能,不再有任何限制,不论是家庭还是企业都可以自由使用,当然,随之而来的还有更高的成本。

2. 私有化部署的条件

Bitwarden 服务端的作用是保存密码,重要性不言而喻,私有化部署把你自己变成了数据安全的第一责任人,所以需要你至少具备以下能力:

  1. 知道如何购买云服务器和域名(或已经拥有云服务器和域名)
  2. 熟练的管理 Linux 服务器,掌握基本的数据备份和恢复技能。
  3. 熟练的使用 Docker 或 Podman 等容器化技术
  4. 熟悉 Web 服务器软件、HTTPS 和反向代理
  5. 知道如何管理和解析域名

知识技能暂且放在一边,这里单说价格。便宜的低配云服务器基本也要 30 元/月,域名可以算 60 元/年,这样加起来一年大概就需要 420 元,而买 Bitwarden 官方的高级会员一年不过就是 70 元($10),况且还可以选择一分钱不用花的免费版。这足以说明 Bitwarden 的私有化部署对大多数人来说都不是一个理想的选择。

如果你具备上述所有条件,而且你愿意用更高的成本换取更多的掌控、隐私安全或者其它你所期望能力,那么请准备好以下资源:

2.1 云服务器

  • 一个固定公网 IPv4 地址
  • 至少 1 核 CPU、1GB 内存、20GB 硬盘
  • 支持运行 Docker 或 Podman 的 Linux 发行版,建议 Almalinux、Rocky Linux、Ubuntu Server、Debian。
  • 中国大陆地区的云服务器运行网站程序必须依法备案,如果部署的 VaultWarden 服务端仅用于学习和自用,可以购买免备案的港澳台或海外地区云服务器,详情参考《国内外常用云计算平台汇总》。
是否需要网站备案的界定?
只要部署在中国大陆地区服务器上的程序能够通过域名公开访问,那么这个网站就需要进行工信部备案和公安备案。

2.2 域名

  • 一个国际域名,可以到 NameCheap 注册特价域名
  • 域名 A 记录解析到云服务器的公网 IP
  • 并不是所有域名都支持备案,如果你计划为 VaultWarden 服务端备案,请参考《最新支持备案域名后缀列表》选择域名。

3. 服务端方案选择

所谓 Bitwarden 服务端是密码管理器保存密码的地方,在不做任何选择的情况下,默认是使用 Bitwarden 官方服务器来创建账户和保存密码的。而部署私有的服务端,就是在自己的服务器上创建账户和保存密码。

部署私有服务端有两种版本可选,一个是 Bitwarden 官方维护的版本,另一个是由社区用户采用 Rust 语言重写的开源版本 vaultwarden

3.1 Bitwarden 官方版

Bitwarden 官方维护的服务端采用 C# 编写,需要使用 Docker 和 Docker Compose 部署,镜像文件体积在 260 MB 左右,默认采用 MariaDB 数据库,也可以通过修改 docker-compose.yml 中的配置改用 PostgreSQL 或 MS SQL 数据库。

curl -s -L -o bitwarden.sh \
    "https://func.bitwarden.com/api/dl/?app=self-host&platform=linux" \
    && chmod +x bitwarden.sh
./bitwarden.sh install
./bitwarden.sh start
Bitwarden self-host 官方版服务端部署命令

对于 Bitwarden 官方版服务端,这里点到为止,后文将着重介绍 vaultwarden 的部署和使用。

3.2 VaultWarden 社区版

Vaultwarden 原名 bitwarden_rs,是开源社区用户使用 Rust 语言重写的 Bitwarden 服务端,与 Bitwarden 公司没有任何隶属关系。

得益于 Rust 语言实现,VaultWarden 非常轻量,在系统资源占用上,包括 Postgres 数据库在内也不过就 123 MB 左右。一般来说,一个低配 VPS 云服务器即可满足运行要求。

vaultwarden memory used

4. 云服务器环境

风险提示:下文要部署的是保存密码的服务端程序,从程序到系统再到硬件,所涉及的任何一个环节出现漏洞都会造成不可估量的损失。本文旨在抛砖引玉,无法提供绝对安全的指导建议,请自行评估可能存在的风险。

4.1 防火墙

强烈建议为服务器开启防火墙,且仅开放必要的端口,比如:

  • 443 - HTTPS 协议的默认端口
  • 22 - SSH 协议的默认端口
注意:80 端口是 http 协议的默认端口,由于它采用明文通信存在安全隐患,建议不要使用。

有些云平台会提供硬件防火墙,可以在用户控制台设置,如果没有的话也可以使用 Linux 发行版自带的防火墙。

4.2 SSH 免密登陆

一般情况下,云服务器默认采用 SSH 密码认证的方式进行远程登陆。有些平台也支持在创建服务器时加载公钥,不论如何,你需要做到:

  • 禁用 SSH 密码认证方式,即编辑 /etc/ssh/sshd_config 配置文件,将 PasswordAuthentication 的值修改为 no。
  • 启用 SSH 密钥认证方式,即编辑 /etc/sshd/sshd_config 配置文件,将 PubkeyAuthentication 的值修改为 yes。

4.3 Web 服务器软件

Apache、Nginx 是大家常用的 Web 服务器软件,但这里想向大家强烈推荐一下 Caddy,一款自动实现 https 证书申请和配置的 Web 服务器软件,本文会以 Caddy v2 为例进行介绍。

Caddy 可以直接运行在服务器上,也可以运行在容器中,两种方式在管理上稍有区别,但并无优劣之分,如何选择主要看你的个人便好。

4.4 容器运行时

本文分享的方案需要将 VaultWarden 运行在容器中,所以需要预先在服务器中安装并启用一种容器运行时,Docker 或 Podman 都可以。

5. 部署 VaultWarden

文会以 Podman 为例进行介绍,因为 Docker 和 Podman 的用法命令几乎一致,如果你使用的是 Docker,直接将下文命令中的 podman 替换成 docker 就可以了。

5.1 目录结构

建议创建一个  vaultwarden  文件夹来管理容器相关的脚本,所有相关的文件和目录都放在这里面,例如:

vaultwarden/
├── app.sh
├── data
├── db.sh
└── pod.sh
目录结构

5.2 Pod

Podman Pod 与 Kubernetes 的 Pod 类似,可以把程序和数据都放到同一个 Pod 里面,里面的容器共享同一个 localhost 网络,彼此直接使用端口号进行通信,对外的端口通过 Pod 统一进行映射。

pod.sh 脚本内容:

#!/bin/bash
sudo podman pod rm -f vaultwarden
sudo podman pod create --name vaultwarden \
-p 10001:80
创建 Pod

5.3 Database

VaultWarden 支持 SQLite、MariaDB/MySQL、PostgreSQL 三种数据库:

  • SQLite:单文件数据库,无需额外配置即可直接使用,适用于用户数量不多的情况使用;
  • MariaDB/MySQL:网络数据库,需要单独部署,适用于用户数量多的情况;
  • PostgreSQL:网络数据库,需要单独部署,适用于用户数量多的情况;

这里提供一份 PostgreSQL 的部署脚本,使用 SQLite 数据库时可以忽略。

db.sh 脚本内容:

#!/bin/bash
sudo podman pull postgres:alpine
sudo podman rm -f vaultwarden-db
sudo podman run -d --name vaultwarden-db \
  --pod vaultwarden \
  -e POSTGRES_DB="vaultwarden" \
  -e POSTGRES_PASSWORD="your-password" \
  -v vaultwarden_db_data:/var/lib/postgresql/data \
  postgres:alpine
PostgresSQL 部署脚本

5.4 APP

app.sh 脚本(SQLite 数据库版):

#!/bin/bash
sudo podman pull vaultwarden/server:latest
sudo podman rm -f vaultwarden-app
sudo podman run -d --name vaultwarden-app \
  --pod vaultwarden \
  -v data:/data/:Z \
  -e ROCKET_PORT=80 \
  vaultwarden/server:latest

app.sh 脚本(Postgres 数据库版):

#!/bin/bash
sudo podman pull vaultwarden/server:latest
sudo podman rm -f vaultwarden-app
sudo podman run -d --name vaultwarden-app \
  --pod vaultwarden \
  -v data:/data/:Z \
  -e ROCKET_PORT=80 \
  -e 'DATABASE_URL=postgresql://postgres:your-password@localhost:5432/vaultwarden' \
  vaultwarden/server:latest
VaultWarden 部署脚本(Postgres 数据库)

注意倒数第二行数据库设置的部分,直接使用 localhost:5432 访问数据库容器,这就是在 Pod 中管理容器的好处。

VaultWarden 的一些管理功能需要通过环境变量在部署时传递给容器,比如禁止用户注册,并开启管理后台:

#!/bin/bash
sudo podman pull vaultwarden/server:latest
sudo podman rm -f vaultwarden-app
sudo podman run -d --name vaultwarden-app \
  --pod vaultwarden \
  -v data:/data/:Z \
  -e ROCKET_PORT=80 \
  -e 'DATABASE_URL=postgresql://postgres:your-password@localhost:5432/vaultwarden' \
  -e ADMIN_TOKEN=your_long_password_for_admin_auth \
  -e SIGNUPS_ALLOWED=false \
  vaultwarden/server:latest

5.5 执行部署

在 vaultwarden 目录下依次执行以下命令:

# 创建 pod
bash pod.sh
# 部署 postgre 数据库(如果使用 Postgres 数据库)
bash db.sh
# 创建 data 目录
mkdir data
# 部署 vaultwarden server
bash app.sh

5.6 配置 Caddy 反向代理和 HTTPS

使用 Caddy Server 对 vaultwarden 做反向代理并自动申请配置 SSL 证书,编辑 /etc/caddy/Caddyfile 根据你的域名添加配置:

your.domain.com {
  reverse_proxy 10.88.0.1:10001
}

这里的 10.88.0.1 IP 地址是 Podman 分配的内网网关地址,端口号 10001 是 Pod 中定义的宿主机映射端口,可以根据需要灵活修改。

在主机上通过 ip a 可以查到容器的虚拟网卡接口信息:

$ ip a

3: cni-podman0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether e6:4c:e7:16:8a:7d brd ff:ff:ff:ff:ff:ff
    inet 10.88.0.1/16 brd 10.88.255.255 scope global cni-podman0
       valid_lft forever preferred_lft forever

至此,访问 https://your.domain.com 即可打开 vaultwarden 界面开始使用了。

5.7 配置容器开机自启动

Podman 是 deamonless 的容器运行时,开机自启动需要通过 Linux 的 systemd 进行配置,好在 Podman 提供了 generate 命令可以为容器生成 service 脚本。指定容器名或 Pod 名生成容器即可:

sudo podman generate systemd -f -n vaultwarden

这条命令会在当前目录生成:

  • pod-vaultwarden.service
  • container-vaultwarden-app.service
  • container-vaultwarden-db.service (如果采用 Postgres 数据库的话)

把生成配置文件复制到 /lib/systemd/system/ 目录:

sudo cp pod-* container-* /lib/systemd/system

然后启用服务:

sudo systemctl enable --now pod-vaultwarden
注意:因为容器隶属于 pod,因此只需要启用 pod-vaultwarden.server 即可,它会关联控制所有相关容器的启动、重启和停止。

6. 使用

完成前述的部署流程,确认 VaultWarden 可以通过你自己的域名访问,然后就可以在任何 Bitwarden 客户端上进行登陆和使用了。

如下所示,在 Bitwarden 客户端界面找到“设置“,在自托管环境中添加自己的 VaultWarden 服务器地址保存即可。

Bitwarden 设置使用自托管服务器