· 9 min read

抛弃 Bitwarden 官方 docker!基于 Vaultwarden 搭建自己的密码托管服务

Bitwarden 是一套开源的密码管理系统, Vaultwarden 是与其服务器端 API 兼容的轻量化实现. 借助 Vaultwarden 服务端和 Bitwarden 的全平台客户端, 可以搭建一个完整的密码管理服务

概述

现在 Chrome 等主流浏览器都内置了密码管理器, 国内不少手机厂家也有自己的密码管理服务, 苹果生态内更是能体验到非常完善的密码管理与同步. 那么, 为什么还要自建一套密码管理服务呢? 就我个人的使用场景而言, 目前主流的密码管理服务主要存在如下不足:

  • Chrome, Edge 等浏览器的密码管理服务以及苹果等厂商的服务与自家软硬件生态深度绑定, 多平台多设备使用体验非常割裂, 想在诸多搭载不同系统的设备之间进行密码同步简直是噩梦
  • 客户端支持的平台不足. 比如你很难将 Chrome 和 Edge 的密码管理服务用于命令行, macOS 和 iOS 的系统级密码管理服务在苹果生态内体验虽佳, 但是在 Windows 和 Linux 平台却无能为力
  • 不支持更高程度的自定义. 这些密码管理服务并不太开放, 因此无法根据自己的使用场景和习惯进行调整. 比如 URI 匹配策略这个细节, 上面提到的密码管理器的匹配策略比较简单且不支持自定义, 经常出现该匹配的时候匹配不上或者将某些网站混起来, 提示/自动填充不够精准等问题
  • 1password 等密码管理器能够提供比较完美的全平台使用体验, 但是订阅费用还是有点高

考虑到当前密码管理器产品存在的这些不足, 我选择了自建密码管理服务.

Bitwarden 是一款开源的密码管理器, 提供了 Windows, macOS, Linux, iOS, Android, 浏览器插件和 CLI 等各种客户端, 几乎可以覆盖所有的使用场景. 更重要的是, 它还提供了开源的服务器端程序, 可以自行托管所有服务, 对于个人或者团队来说非常友好.

除了常规的密码储存和自动填充服务, Bitwarden 还集成了一系列实用工具, 包括张户名和密码生成器, 密码安全性报告生成器等. 这些工具大大减轻了保证密码安全过程中的痛苦, 能够帮助用户养成更加健康的密码安全习惯.

当然, 自建密码管理服务会面临一系列的麻烦和风险. 例如你需要做很多额外的安全措施来保证密码库的安全; 需要花费一定的代价来保证密码服务的高可用性等等; 自建的服务与系统/浏览器的配合可能没有它们自带的服务那么天衣无缝等等.

Vaultwarden 简介

Bitwarden 官方开源了其服务器端程序, 并提供了 Docker 镜像以便用户自行部署. 但是, 官方的实现过于臃肿, 对宿主机性能造成了很大的负担, 并且仅仅支持 amd64 架构, 在很多场景下部署起来也有所不便.

vaultwarden 是一个由 Rust 写成的与官方 server 端 API 兼容的服务器端程序, 它实现了 Bitwarden 官方服务器端的绝大部分功能, 并且非常轻量化, 还支持 arm 架构. 项目主页:

dani-garcia/vaultwarden: Unofficial Bitwarden compatible server written in Rust, formerly known as bitwarden_rs (github.com)

关于 Vaultwarden 所实现和没有实现的功能特性参考项目 wiki:

Home · dani-garcia/vaultwarden Wiki (github.com)

对个人用户而言影响最大的可能是暂时还不支持 Android 和 iOS 的系统级推送服务, 导致移动客户端上的密码更新同步等可能不够及时, 不过可以通过设置好移动端同步策略来改善此问题.

基础部署

要让 Vaultwarden 跑起来非常简单, 参考 wiki 中的 Docker Compose 文件:

services:
  vaultwarden:
    image: ghcr.io/dani-garcia/vaultwarden
    container_name: vaultwarden
    restart: unless-stopped
    volumes:
      - /path/to/vaultwarden/data/:/data/

启用 admin page

Vaultwarden 支持通过环境变量更改服务器设置, 也额外实现了一个管理面板, 以一种更友好方式进行配置.

要启用 admin page, 只需要在运行 docker 时加上 ADMIN_TOKEN 环境变量. 要获取 token 有很多种方式, 推荐通过运行一个 docker 容器来获取:

docker run --rm -it vaultwarden/server /vaultwarden hash

该命令会提示用户输入一个密码, 随后会对用户输入的密码进行加密, 并返回加密后的密码.

注意, 如果要在 docker compose 中配置 token, 需要在 token 中本身出现的 $ 符号前面加上一个 $ 来 escape, 例如:

environment:
    ADMIN_TOKEN: $$argon2id$$v=19$$m=19456,t=2,p=1$$UUZxK1FZMkZoRHFQRlVrTXZvS0E3bHpNQW55c2dBN2NORzdsa0Nxd1JhND0$$cUoId+JBUsJutlG4rfDZayExfjq4TCt48aBc9qsc3UI

启用后, 可以在 https://<your-domain>/admin 访问管理面板.

参考:

Enabling admin page · dani-garcia/vaultwarden Wiki (github.com)

启用 websocket 推送

Vaultwarden 实现了一个 websocket 服务, Bitwarden 的桌面客户端和浏览器插件客户端可以与服务器建立一个 websocket 连接, 从而在任意设备上修改密码后变动会及时同步到其他设备.

要启用 websocket 特性, 只需要加上环境变量:

environment:
  WEBSOCKET_ENABLED: true

websocket 服务默认监听 3012 端口. 但是仅仅这样配置还不够, websocket 服务需要配合反向代理才能正常使用, 具体来说, 需要将 /notifications/hub 路径路由到 websocket 监听端口, 将其他流量路由到 80 端口.

好在项目 wiki 上提供了针对目前主流反向代理服务器程序的配置示例:

Proxy examples · dani-garcia/vaultwarden Wiki (github.com)

关于如何启用 websocket 特性的更多内容参考:

Enabling WebSocket notifications · dani-garcia/vaultwarden Wiki (github.com)

配置好 websocket 之后, 可以在 Web Vault 登录界面打开浏览器开发者工具, 在 Network 标签页过滤出 WS 流量, 并执行登录操作. 登录成功后, 如果出现一个 websocket 连接, 并且其状态码为 101 Switching Protocols 即说明 websocket 配置正确.

正确配置 websocket 的效果

此外, 还可以通过实践的方式检验 websocket 同步效果. 打开两个无痕窗口, 分别登录 Web Vault, 在其中一个窗口中添加一条密码记录, 如果 websocket 配置成功, 另一个窗口中应该也能立即看到新增的记录.

数据备份

如果采用 docker 方式运行, vaultwarden 的所有数据都被存储在挂载的 Volume 中, 只需要备份该 Volume 即可.

比较在意数据安全性的话, 可以在备份时做个加密.

关于 Vaultwarden 的数据备份参考:

Backing up your vault · dani-garcia/vaultwarden Wiki (github.com)

提升安全性

关于如何提升密码库安全性, wiki 上也给出了一些思路, 参考 wiki 中 Security 一节.

参考

Vaultwarden 汉化版 wiki:

首页 - Vaultwarden Wiki 中文版 (ppgg.in)

Bitwarden 官方文档:

Help Center | Bitwarden

Share:
Back to Blog

Related Posts

View All Posts »

再次重构站点小记

再次重构和迁移博客, 切换了主题、框架, 切换了部署平台, 重新寻找图床解决方案, 撰写博客的方式也发生了变化. 此外, 还为博客新增了基于 giscus 的讨论区和基于 Umami 的访客统计

Linux 本地化 - locale 变量与设置方法

Linux 中通过 locales 调整语言, 编码以及其他本地化设置, 如果设置不当可能导致乱码等问题. 本文介绍 Linux 中 locales 变量的作用以及 locales 的设置方法