在 Linux 搭建密码管理服务 Vaultwarden
Vaultwarden 是一个开源的密码管理器,与商业产品 Bitwarden 服务器兼容。因此可使用 Bitwarden 的 Web客户端、桌面或者移动客户端管理密码连接 Vaultwarden 服务器。从用户的角度来看,二者组合起来的体验类似于商业产品 1Password 。 本文介绍自建 Vaultwarden 服务的步骤和注意事项。
产品特性
Vaultwarden 是与 Bitwarden 兼容的服务器实现,其 Wiki 页面 列出了它所支持的特性,以及缺失的特性。对于用于个人的密码管理场景,Vaultwarden 的特性基本够用。
运行 Vaultwarden 服务
Vaultwarden 提供了包括 x86_64,arm 等架构的官方 Docker 镜像,用于在容器中运行,参见 《Starting a Container》,在此不做赘述。下文介绍在没有 Docker 环境时,直接使用二进制文件运行 Vaultwarden
准备 vaultwarden 可执行文件
如果没有 Docker 环境,那么可直接运行 vaultwarden 可执行文件运行服务。为此,可自行编译源代码,或者从官方的 Docker镜像中提取可执行文件和Web客户端。
docker-image-extract 这个 Shell 脚本可用于从 DockerHub 下载镜像并提取内容,具体操作说明见《Extracting binaries without Docker installed》。
注意:由于众所周知的原因,在国内可能无法连接 DockerHub。需要有变通方法。比如设置代理相关的环境变量
http_proxy和https_proxy。
比如,对于 ARMv7 (32位)架构平台,可使用如下命令提取 Docker镜像内容:
docker-image-extract -p linux/arm/v7 vaultwarden/server:latest-alpine该命令会把 Docker镜像的内容保存到 output 目录下,该目录下的文件如下:
$ ls -1 outputbindatadevetchealthcheck.shhomelibmediamntoptprocrootrunsbinsrvstart.shsystmpusrvarvaultwardenweb-vault我们需要的是可执行文件 vaultwarden 和 web-vault 目录。
创建专有用户
创建一个专有用户,用于运行 Vaultwarden:
adduser vaultwarden将 vaultwarden 加入到系统路径中
为了便于使用 vaultwarden 命令,可将 vaultwarden 可执行文件放在服务器的系统路径下,比如 /usr/local/bin 目录下。
准备 Vaultwarden 目录
Vaultwarden 在运行时需要一个工作目录,其中包含:
data目录,用于保存数据库、图标等文件。web-vault即 Web客户端的前端代码。
为此,创建一个工作目录,比如 /usr/local/lib/vaultwarden,并将其所有者修改为 vaultwarden:
mkdir /usr/local/lib/vaultwarden/mkdir /usr/local/lib/vaultwarden/data然后,将从 Docker 镜像中提取的 web-vault 目录,放在 /usr/local/lib/vaultwarden/ 目录下。
在创建一个环境变量文件,用于设置环境变量:
touch /usr/local/lib/vaultwarden/.env为了安全起见,设置 vaultwarden 相关文件的所有者和文件权限:
chown -R vaultwarden:vaultwarden /usr/local/lib/vaultwardenchmod -R o-r /usr/local/lib/vaultwardenchmod -R o-x /usr/local/lib/vaultwarden创建 Systemd 系统服务
创建服务文件 /etc/systemd/system/vaultwarden.service,内容如下:
[Unit]Description=vaultwardenAfter=network.target
[Service]Type=simpleUser=vaultwardenWorkingDirectory=/usr/local/lib/vaultwardenEnvironmentFile=/usr/local/lib/vaultwarden/.envExecStart=vaultwardenRestart=on-failure
[Install]WantedBy=multi-user.target启动服务
systemctl start vaultwarden然后查看运行状态:
systemctl status vaultwarden也可查看运行日志:
journalctl -u vaultwarden如果日志中出现以下内容,说明服务已经启动:
[start][INFO] Rocket has launched from http://127.0.0.1:8000此时,虽然服务启动了,并且在服务器上可通过 curl localhost:8080 访问,但却无法通过浏览器从其他机器使用 IP 地址访问。这不仅仅是因为服务绑定在了 127.0.0.1 而不是 0.0.0.0。还因为,由于安全原因,Web客户端使用了浏览器的加密接口,而这些加密家口,必须在使用 HTTPS 访问时才能使用。如果将 Vaultwarden 绑定在 0.0.0.0,然后在其他机器的浏览器上通过IP 地址访问,在登录时,那么就会看到错误提示:“This browser requires https to use the web vault”。因此,为了能够从服务器之外访问 Vaultwarden,启用 HTTPS 是必须的。
启用 HTTPS
Vaultwarden 的《Enabling HTTPS》 介绍了启用 HTTPS 的不同方法。在这里,介绍的是通过域名获取免费的 SSL 证书,然后通过反向代理启用 HTTPS 的方法。
Caddy服务器不仅提供反向代理功能,而且能够自动地获取和续订 SSL 证书。如果服务器被暴露给公网,可以被证书提供商访问,那么使用 Caddy 是最简单的方法。如果服务存在与内网之中,那么可使用 DNS 记录验证域名和获取 SSL 证书。本文介绍后者。
获取 SSL 证书
为了获取合法的 SSL 证书,那么就要一个真实的域名,并让证书提供方验证域名的所有权。
接下来本示例通过命令行工具 Lego,使用 DNS 记录验证域名并获取 SSL 证书。假设如下:
- 期望通过域名访问 Vaultwarden,且拥有该域名的所有权,可对其 DNS 记录进行修改。
- 可通过 API 管理 DNS 记录。下文以 Cloudflare 为例。
以 Cloudflare 为例,参考 Lego 的《Cloudflare》 文档,操作步骤如下:
- 创建 API Token。为了缩小权限,可设置其权限为
Zone - Zone:Read和Zone - DNS:Edit。 - 使用如下
lego命令和参数获取证书:
CLOUDFLARE_DNS_API_TOKEN={api token} lego --email {email} --dns cloudflare -d '{domain}' --dns.resolvers "8.8.8.8" run注意:这里使用了
--dns.resolvers参数是为了获取4级域名的证书。如果域名是一级、二级或者三级域名,那么不需要这个参数。具体参见 《[cloudns] unable to request certificate for fourth level domain #884》。
根据命令的输出提示,获取到的证书位于当前目录下的 .lego/certificates 目录下。其中证书和私钥文件分别为 {domain}.crt 和 {domain}.key
注意:使用该方法获取到的证书,有效期只有3个月。因此需要在到期前续订证书。
配置反向代理
以下 Nginx 为例,配置反向代理服务器。
首先将 SSL 证书放置在服务器上的 Nginx 配置目录中,比如 /etc/nginx/conf.d/ 目录下。然后创建配置文件:
server { server_name {domain}; listen 443 ssl; ssl_certificate /etc/nginx/conf.d/{domain}.crt; ssl_certificate_key /etc/nginx/conf.d/{domain}.key; location / { proxy_pass http://localhost:8000; }}然后检查配置:
nginx -t如果配置无误,那么让 Nginx 重新加载配置:
nginx -s reload验证
打开浏览器,使用 https 访问 Nginx 配置的域名。顺利的话,就会打开 Vaultwarden,并且可以创建用户、登录并管理密码了。
使用其他客户端
还可使用 Bitwarden 的客户端使用 Vaultwarden。比如 Chrome浏览器扩展 Bitwarden Password Manager 和桌面客户端等,见 Bitwarden 的下载页面。