使用群晖搭建第三方 Bitwarden 密码服务器

   Updated: 2021-12-28 14:40       使用群晖搭建第三方 Bitwarden 密码服务器有46条评论

bitwarden_rs 项目从 v1.21.0 开始,已更名为 Vaultwarden。仅名称更改,其他不变,以下内容将 bitwarden_rs 改为 vaultwarden 即可。

本文介绍如何在自己的群晖上搭建第三方 Bitwarden(bitwarden_rs)密码管理服务器。更多部署 Bitwarden 的信息请参考 Bitwarden 的部署和使用

基于安全性和稳定性考虑,如果您对 Bitwarden 依赖比较大,不建议使用在群晖上搭建 bitwarden_rs 的方式。建议使用官方 Bitwarden 云服务,或在自己的 VPS 上搭建 Bitwarden 或 bitwarden_rs。

Bitwarden 和 bitwarden_rs 介绍

Bitwarden 介绍

Bitwarden 是一个跨平台的密码管理软件,类似于 1Password、EnPass、LastPass 等,支持几乎目前所有的平台(Mac、PC、Linux、iOS、Android、网页浏览器、浏览器扩展)。Bitwarden 是开源的,可以将服务端部署在自己的服务器上,比如群晖的 Docker 中。

提供个人账户(免费版和高级会员版)和组织账户(免费版、家庭版、团队版和企业版)。查看各版本的区别

Bitwarden 个人账户的免费版不限制使用时间、不限制密码条目数、不限制设备数量、不限制文件夹数量、支持常见的验证器应用程序,对于大部分人日常使用已经足够。如果你要使用高级功能(如 Yubikey、TOTP、文件附件),可以以 $10/年购买高级会员版,相对 1Password 已经是非常良心的价格了。

Bitwarden 的优点:

  • 客户端界面简洁(我觉得是优点)
  • 大部分功能免费,价格良心
  • 可以使用 Bitwarden 的云也可以自己本地部署
  • 有支持高级功能的免费的第三方开源 bitwarden_rs 项目

Bitwarden 的缺点:

相比较,1Passwords 更为方便,界面也更华丽。

Bitwarden 的介绍、配置和使用请参阅 Bitwarden Help Center,或者我翻译的中文版

bitwarden_rs 介绍

bitwarden_rs 是一个用于本地搭建 Bitwarden 服务器的第三方开源 Docker 项目。

bitwarden_rs 使用 Rust 编写,并改用 SQLite 数据库(现在也支持 MySQL 和 PostgreSQL),相对于官方版使用 MSSQL 数据库要求至少 2GB 内存,运行 bitwarden_rs 时只需要 10M 内存,可以说对硬件基本没有要求。

除不支持官方企业版的部分功能(如事件日志、目录同步、SSO 登录以及基于企业组织层面的 DUO Security 两步登录)外,其他大部分功能均免费支持。并跟随官方版本保持及时更新。

仅在部署的时候使用 bitwarden_rs 镜像,桌面端、移动端、浏览器扩展等客户端均使用 Bitwarden 官方的客户端应用程序。

bitwarden_rs 的介绍、配置和使用请参阅 bitwarden_rs wiki 页面,或者我翻译的中文版

01-确认你的环境

准备您的环境:

  • 支持 Docker 的群晖(黑白均可)
  • 宽带(是否公网 IP 都可以)
  • 自己的域名(这里以域名 b.ppgg.in 为例)
  • 域名证书文件(可选)

域名证书可以在阿里云或 dnspod(我使用 dnspod)申请有效期一年的免费证书,申请好以后下载备用。

为了安全,需要启用 SSL,而启用 SSL 需要证书。如果你不启用 SSL,Chrome 浏览器和 iOS 客户端将不能正常使用,其他浏览器和客户端没问题。

02-搭建 Bitwarden 服务端

这里使用群晖自带的反向代理的方式开启 SSL。如果你不启用 SSL,那下面与证书、SSL、反向代理相关的步骤可以跳过。

001-准备工作

群晖上安装 Docker

直接在群晖的套件中心搜索 Docker 并安装即可。

新建用于存放数据文件的文件夹

文件夹的位置和名称你自己随意,我这里为 docker/bitwarden/data

002-Docker 里安装并配置 Bitwarden

下载 bitwarden_rs 镜像

打开群晖 Docker,「注册表」 中搜索 bitwardenrs,双击 bitwardenrs/server 并选择 latest 下载。这个 bitwardenrs/server 是新版镜像,老版镜像是 mprasil/bitwarden,老版镜像已被新版镜像替代并已停止更新。

配置容器参数

镜像下载完成后,到 Docker-映像,双击打开下载好的镜像,点击 「高级设置」 做如下配置。

添加数据文件的存储路径:「卷」 中添加 「文件夹路径」 docker/bitwarden/data(根据你建的文件夹的路径修改);「装载路径」 /data/(不要修改)

修改 「端口设置」:修改容器端口为 80(不需要更改)所对应的本地端口为 8080(你自己定义,只要不与群晖已使用的端口冲突即可,有冲突会有提示);类型保持默认为 TCP(新版镜像有一个容器端口为 3021 的条目,可以删除掉或者不用管它,这个是 WebSocket 的默认端口,我也不知道啥用)

其他按照默认,单击应用以保存。

003-群晖中设置反向代理

1、进入群晖的 「控制面板」-「Synology 应用程序门户」-「反向代理服务器」 页面,如图添加一条 「反向代理服务器规则」。(「来源端口」 你自己定义,这里假如为 28080;「目的地端口」 对应上面配置容器参数步骤中设置的本地端口 8080)

2、进入群晖的 「控制面板」-「安全性-「证书」 页面,将你的域名证书文件和私钥文件导入群晖中。

以 dnspod 申请的证书为例。将下载下来的证书文件压缩包解压。如图导入群晖中:

  • Nginx 文件夹里的 2_b.ppgg.in.key 文件放入 「私钥」 中
  • Nginx 文件夹里的 1_b.ppgg.in_bundle.crt 文件放入 「证书」 中
  • 「中间证书」 留空

或者

  • Apache 文件夹里的 3_b.ppgg.in.key 文件放入 「私钥」 中
  • Apache 文件夹里的 2_b.ppgg.in.crt 文件放入 「证书」 中
  • Apache 文件夹里的 1_root_bundle.crt 放入 「中间证书」 中

3、在 「证书」 页面设置刚才添加的反向代理服务器规则使用此证书。

注意:导入的证书要包含中间证书,否则会导致安卓版的 Bitwarden 客户端无法登陆。如果你使用不带中间证书的证书,又希望你的安卓客户端能正常使用,解决方法就是把中间证书安装到你的安卓手机上。安装方法见后文。

至此,Bitwarden 服务端基本就搭建好了。启动 Bitwarden 容器后,浏览器输入 https://群晖的 ip:28080(不启用 SSL 则为:http://群晖的 ip:8080),应该就可以进入登录页面了。

如果你只是打算在内网中使用 Bitwarden,那到这里就搭建完成了。除了在 Chrome 浏览器中不能登录和注册以及 iOS 客户端不能使用外,其他浏览器和客户端都可以正常使用 Bitwarden 了。

004-设置外网访问 Bitwarden 服务端

根据你的宽带是否有公网 IP,有两种方式:

  1. 有公网 IP:如果是动态公网 IP,你还需要做 DDNS 域名解析。有公网 IP 就比较简单,设置端口转发即可。访问 Bitwarden 服务端的速度取决于你宽带的上行速度。
  2. 无公网 IP:可以利用内网穿透的方式,比如 frp。相对要求高也麻烦一些,需要你自己在你的 VPS 上搭建或购买内网穿透服务(如花生壳盒子)。由于有中转过程,访问 Bitwarden 服务端的速度还受到内网穿透服务器的影响。

查看自己的宽带是否有公网 IP 的方法:浏览器访问 http://ip138.com/ 查看你的 IP 地址,对比你的路由器中 WAN 获取到的 IP 地址,如果这两个 IP 地址一样,那说明是公网 IP,不一样则不是公网 IP。

根据你的实际情况做相应的如下设置:

有公网 IP

  1. 先配置 DDNS:在你内网的任一台机器(路由器或者群晖等)设置好 DDNS 服务,当然你如果是固定的公网 IP 就不需要设置 DDNS。DDNS 的设置方法这里就不写了,网上有很多教程。
  2. 然后在路由器上设置端口转发:外网的 28080 端口(对应上面群晖反向代理中您设置的来源端口)转发到内网群晖 IP 地址的 28080 端口(同样对应上面群晖反向代理中您设置的来源端口,这里要注意)。

无公网 IP

我的宽带没有公网 IP,所以无法使用 DDNS,但我有使用 frp 做内网穿透,见我另一篇文章搭建 frp 内网穿透以访问 NAS

修改 frpc 客户端配置文件 frpc.ini,增加如下配置:

[Bitwarden_server]
type = tcp
local_ip = 192.168.99.100 # NAS 的内网 IP。如果 frpc 客户端搭建在 NAS 上,所以这里也可以直接 127.0.0.1,但是我用 127.0.0.1 会无法访问,改成实际的内网 IP 地址就好了
local_port = 28080 # 映射到 NAS 上的本地端口(对应上面群晖反向代理中您设置的来源端口)
remote_port = 28080 # 远程访问端口(同样对应上面群晖反向代理中您设置的来源端口)

03-搭建完成

经过以上设置,群晖上 Bitwarden 服务端的搭建就完成了。

浏览器:使用 https://b.ppgg.in:28080

客户端:自托管环境服务器 URL 填写 https://b.ppgg.in:28080

不使用反向代理开启 SSL 的方法

如果你不使用群晖的反向代理,要开启 Bitwarden 的 SSL,则需要将证书文件挂载到 Bitwarden 容器中。

1、参考新建用于存放数据文件的文件夹步骤,这此步骤上再新建用于存放证书文件的文件夹(假如为 docker/bitwarden/ssl),并将证书文件和证书证书私钥文件放到此文件夹中。

同样注意:证书文件中要包含中间证书内容,否则会导致安卓版的 Bitwarden 客户端无法登陆。如果你使用不带中间证书的证书文件,又希望你的安卓客户端能正常使用,解决方法就是把中间证书安装到你的安卓手机上。安装方法见后文。

关于证书文件的说明:

  • xxx.crt 和 xxx.key 文件可以随意重命名,甚至使用任意的扩展名。虽然网上很多教程使用的是.pem 的扩展名。
  • 与群晖中导入证书不同,群晖可以单独导入中间证书文件,而这里只有一个证书文件。如果你的 xxx.crt 证书文件中不包含中间证书内容,可以使用文本编辑器,将中间证书文件的全部内容简单地复制并粘帖到 xxx.crt 文件内容的下一行即可(另一个更简单的办法是将证书文件含中间证书文件导入群晖,再从群晖中导出来使用)。

2、参考配置容器参数步骤,在此步骤上再添加证书文件的存储路径:「卷」 中添加 「文件夹路径」docker/bitwarden/ssl(根据你建的文件夹的路径修改);「装载路径」/ssl/(不能修改)

3、设置端口转发(或 frp)与使用反向代理时有点不一样

  • 有公网 IP:设置端口转发,外网的 28080 端口转发到内网群晖 IP 地址的 8080 端口(对应上面配置容器参数步骤中设置的容器的本地端口)。如果使用简化域名,这里的外网端口 28080 改为 443 即可。
  • 无公网 IP:修改 frp 客户端配置文件中的 local_port 为 8080(对应上面配置容器参数步骤中设置的容器的本地端口)。

添加 Bitwarden 功能

我们还可以给 Bitwarden 增加其他功能,比如禁用新用户注册、开启二次验证、启用日志记录等。

先来说一下如我这种对 Docker 不太了解的小白如何看懂 docker 的命令参数,并把它配置到群晖 Docker 容器中。

这里以禁用新用户注册功能为例。bitwarden_rs wiki 中相应的教程如下图:

我们看图中 -e SIGNUPS_ALLOWED=false 这一行:-e 对应容器中的 「环境」;SIGNUPS_ALLOWED 表示环境变量的名称;false 表示环境变量的值,如果我们要关闭新用户注册,则可以停止相应容器后编辑,在 「环境」 中添加一行:名称(群晖中叫 「可变」)为  SIGNUPS_ALLOWED,值为  false,保存后再启动此容器即可。

-e:对应容器中的 「环境」
-v:对应容器中的 「卷」
-p:对应容器中的 「端口设置」

更多功能请查看 bitwarden_rs wiki 页面,或我翻译的中文版

禁用新用户注册

添加环境变量 SIGNUPS_ALLOWED=false

禁用邀请

添加环境变量  INVITATIONS_ALLOWED=false

启用日志记录

添加环境变量 LOG_FILE=/data/bitwarden.log

日志级别默认为 「info」,可以参考 bitwarden_rs wiki 更改日志级别。

启用管理页面

添加环境变量 ADMIN_TOKEN=some_random_token_as_per_above_explanation

这里的 some_random_token_as_per_above_explanation 为你自定义的一串任意字符。

开启管理页面后,/admin 子目录即是管理页面地址,如:https://yourdomain.com:8080/admin。你可以登录管理页面查看已注册用户并删除他们、开启二次验证、使用 YubiKey 等更多高级功能。

疑难解答

PC 客户端登录提示 Failed to fetch 错误

我遇到的是由于系统代理设置错误引起:Web 端登录、Chrome 扩展、苹果和安卓客户端使用一切正常,但 PC 客户端登录(以及注册)时提示 Failed to fetch,试过删除账户、重新启动容器、容器操作中使用 「清除」、重装 app 等,都不能解决。

网上找到的只有一篇英文文章 "Failed to fetch" errors on desktop app,然而并没有解决问题。

当时的解决方法:查看群晖及容器都没有相关的日志记录,猜测是没有和服务端建立连接,最后测试发现和 Windows 系统代理设置有关。打开 「Windows 设置-网络和 Internet-代理」,关闭使用设置脚本即可。

安卓客户端登录时提示 「发生错误 There is a problem connecting to the server」

目前还不清楚安卓客户端出现这个错误的具体原因。

我遇到的是 Web 端登录、Chrome 扩展、PC 和苹果客户端等使用一切正常,仅安卓客户端登录提示此错误。

当时的解决方法:经过无数测试和搜索参考,最后将 docker/bitwarden/ssl 中的证书文件 cert.pem 命名为 fullchain.pem 后解决

具体参考 bitwarden_rs wiki 中 Enabling HTTPS 中的这段文字:

Due to what is likely a certificate validation bug in Android, you need to make sure that your certificate includes the full chain of trust. In the case of certbot, this means using fullchain.pem instead of cert.pem.

安卓客户端登陆提示 「发生错误。Exception message:java.security.cert.CertPathValidatorException:Trust anchor for certification path not found.」

这个错误是因为 Bitwarden 的证书文件中缺少中间证书导致安卓系统的证书校验异常(虽然不影响其他平台)。

检查你的证书链是否完整:https://www.digicert.com/help/(支持带端口检测)

解决方法有两种

  • Bitwarden 服务端使用带中间证书的证书文件
  • 或者单独将你域名的中间证书安装到安卓手机中(参考链接

安卓手机安装中间证书的方法

以我的三星 S8 手机为例。将文件名包含 root 字符的 crt 证书文件传到手机中,「设置」 里找到 「生物识别和安全性」-「其他安全设置」-「从设备存储空间安装」,选择刚才上传到手机中的证书,自定义一个证书名,「使用于」 选择 「VPN and apps」。

iOS 客户端可以登录,但同步的时候提示 「无法同步」

这个一般是因为连接不稳定或速度慢导致,多试几次就可以了

错误信息收集及整理

测试并整理了一下各客户端在某些条件下出现的错误信息,以方便出错时定位故障:

不启用 SSL 并使用 http URL(或 IP):

  • Chrome:「发生错误。Cannot read property 'importKey' of null」
  • Microsoft EDGE:正常
  • Firefox:正常
  • Chrome 扩展:正常
  • PC 客户端:正常
  • 安卓客户端:正常
  • iOS 客户端:「发生错误。There is a problem connecting to the server」

不启用 SSL 并使用 https URL:

  • Chrome:「无法访问此网站。ERR_CONNECTION_CLOSED」
  • Microsoft EDGE:「无法安全地连接到此页面」
  • Firefox:「建立安全连接失败」
  • Chrome 扩展:「发生错误。Failed to fetch」
  • PC 客户端:「发生错误。Failed to fetch」
  • 安卓客户端:「发生错误。Exception message:Connection closed by peer」
  • iOS 客户端:「发生错误。There is a problem connecting to the server」

启用 SSL 并使用 http URL:

  • Chrome:「该网页无法正常运作。ERR_EMPTY_RESPONSE」
  • Microsoft EDGE:正常
  • Firefox:「呃…找不到此网站。」
  • Chrome 扩展:「发生错误。Failed to fetch」
  • PC 客户端:「发生错误。Failed to fetch」
  • 安卓客户端:「发生错误。Exception message:unexpected end of stream om com.android.okhttp.Address@8b73cc45」
  • iOS 客户端:「发生错误。There is a problem connecting to the server」

启用 SSL 并使用 https URL 但证书不匹配:

  • Chrome:正常
  • Microsoft EDGE:正常
  • Firefox:正常
  • Chrome 扩展:「发生错误。Failed to fetch」
  • PC 客户端:「发生错误。Failed to fetch」
  • 安卓客户端:「发生错误。Exception message:Hostnamexx.com not verified:certificate...」
  • iOS 客户端:「发生错误。There is a problem connecting to the server」

容器停止或填写了错误的环境 URL 或网络不通:

  • Chrome:「无法访问此网站。ERR_CONNECTION_TIMED_OUT」
  • Microsoft EDGE:「嗯... 无法访问此页面」
  • Firefox:连接超时
  • Chrome 扩展:「发生错误。Failed to fetch」 或 「发生意外错误」 或 「同步失败」
  • PC 客户端:「发生错误。Failed to fetch」 或 「发生意外错误」 或 「同步失败」
  • 安卓客户端:「发生错误。Exception message:Connection closed by peer」 或 「发生错误」 或 「同步失败」
  • iOS 客户端:「发生错误。There is a problem connecting to the server」

其他

备份密码库数据

强烈建议你在做重大操作(如更新 Bitwarden 容器)前先备份你的密码库!!

备份方法有两种:

  1. 客户端程序或网页端里 「导出密码库」(注意:导出操作无法备份文件附件
  2. 备份整个 data 文件夹(这里建议使用群晖中 Hyper Backup 套件来自动增量备份到坚果云)

20200219 我在未备份密码库的情况下做了更新 Bitwarden 容器的操作,然后所有客户端都无法同步了,即使删除 Bitwarden 容器后重新配置也无法解决。幸好 PC 客户端未退出登录,导出密码库再重新导入后才找回了所有密码。

20200402 又遇到同样的故障。

忘记主密码

这个没办法!如果你设置了密码提示并配置了 SMTP,根据密码提示可能能让你想起主密码。如果你开启了两步登录,但两步登录验证程序或你的 Yubikey 丢了,还可以使用恢复代码,前提还是你得知道主密码。

2021 年新增了紧急访问功能。设置了另一个账户作为紧急访问联系人后,紧急访问联系人可以重置主密码(详情见这里)。

mprasil/bitwarden 切换为 bitwardenrs/server

如果你使用的是旧版镜像 mprasil/bitwarden,想切换为新版镜像 bitwardenrs/server,简单地删除旧容器下载新版镜像,然后重新配置即可。

两个镜像使用同样的配置方式,原有的数据文件可以无损切换。但是强烈建议切换之前先做备份

Bitwarden 服务端容器更新方法

具体方法见我的另一篇文章用闲置主机搭建 NAS(黑群晖)及使用

启用三星 S8 中 Bitwarden 客户端的 「自动填充服务」

重启手机后,Bitwarden 的自动填充服务在三星 S8 中被自动禁用的解决:将 Bitwarden 加入 「自启动应用程序」 中即可。

参考链接

46 comments on “使用群晖搭建第三方 Bitwarden 密码服务器

  1. lack

    感谢博主的详细教学解说,搭建成功了,IOS 和 PC 端都可以正常使用了

    Reply
    1. 王小喜 Post author

      iOS 和 PC 端都没问题,那看来浏览器扩展、Andriod 端以及网页版密码库也是没问题了。

      以后对 Bitwarden 比较依赖的话,自己搭建的话一定要做好备份或者使用官方的云服务。

      Reply
  2. mars

    博主,请教个问题。之前的用的好好的,最近更新的新版本的客户端,然后在解锁界面,输入密码永远提示密码错误,然后登出账户,然后用同样的密码 「登入」 账户就又好了。同时,另外有一台电脑,因为没有翻墙环境,所有 chrome 的控件还是老版本就没有这个问题。安卓客户端也是这个问题,但是如果开启指纹,用指纹就又能进行解锁。

    Reply
    1. 王小喜 Post author

      服务器版本太低了吧,不兼容的客户端和服务器版本可能会导致中断或异常。
      bitwarden_rs 最新的发布版本是 1.19.1,对应的 Web 版本是 2.18.1

      Reply
  3. 飞李

    博主 我想问下 我在管理界面点了备份如果我的 bit 重新安装该如何导入备份

    Reply
    1. 王小喜 Post author

      管理员界面点备份后生成的文件名应该类似于 db_20210113.sqlite3,简单地将 db_20210113.sqlite3 覆盖为 db.sqlite3 即可(可能需要先停止 bitwarden)

      Reply
  4. samlin

    你好,我实时备份了 data 文件夹,但是不知道如何做恢复。删除了容器,又新建一个,把原理容器的 data 文件夹覆盖新的容器,还是不能查看到以前的密码列表

    Reply
    1. 王小喜 Post author

      对的,直接覆盖就可以了。

      你恢复之前遇到了啥故障?

      你是实时备份的,很可能你备份的是出故障时的数据,恢复过去当然还是有故障的数据,当然没用了。

      最好的备份方式是定时备份,并且保存多个备份副本,当你发现数据出问题时,总有一个旧的备份是可用的。

      Reply
  5. dd

    搭建成功,浏览器插件正常,ios 端登陆正常,同步提示同步失败,群晖反代,证书也把配置了,web 网页看 ssl 证书正常,不知道哪里的问题,指点一下,谢谢

    Reply
    1. 王小喜 Post author

      iOS 客户端提示 「同步失败」?基本是因为连接速度慢或不稳定,我这里的就经常这样,多试几次就可以了

      Reply
    1. 王小喜 Post author

      当然可以,Enabling admin page

      官方 wiki 有说明:https://github.com/dani-garcia/bitwarden_rs/wiki/Enabling-admin-page

      具体就是添加环境变量 ADMIN_TOKEN,值为你自己定义的任意一串字符

      然后 https://www.youdomin.com/admin 就可以进入管理界面了

      Reply
  6. Stride

    文章中的 docker 用错了,不应该使用 mprasil/bitwarden 应该使用 bitwardenrs/server

    Reply
    1. 王小喜 Post author

      感谢提供这个信息。我看到 Note: you should use bitwardenrs/server instead of this image as that is the new official image.
      这个应该是新版的 Docker 吧,我来试试。

      Reply
  7. 小贝

    发现个小问题 :服务器使用的是 80 端口,苹果手机客户端连击不上,提示: there is problem connecting to the server.
    网页 、 mac 客户端、安卓客户端 都好使。唯独苹果手机不行!

    Reply
    1. 王小喜 Post author

      既然其他客户端可以,就某一设备上的不行,多半就是此设备上系统代理的问题。和我 Windows 客户端遇到的 Failed to fetch 故障应该是一个道理。

      所以,看看你的 iOS 是不是被其他代理程序接管了,或者看一下网络里面的 「配置代理」,正常应该是关闭状态

      Reply

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注