使用群晖自建 Bitwarden 密码服务器

文章目录
[隐藏]

本文介绍如何在自己的群晖 Docker 上搭建第三方 Bitwarden(bitwarden_rs)密码管理服务器,并且让你随时随地通过你的 Mac、PC、iOS、Android 等各平台的 Bitwarden 客户端,以及 Web 浏览器、Chrome 扩展等访问你的 Bitwarden 服务器,编辑并同步你的密码。完全免费,没有密码条目数量的限制,甚至你可以开启两步验证、使用 YubiKey 等。

Bitwarden 介绍

Bitwarden 是一个跨平台的密码管理软件,类似于 1Password、EnPass、LastPass 等,支持几乎目前所有的平台(Mac、PC、iOS、Android、Web 浏览器、Chrome 扩展)。Bitwarden 是免费开源的,可以将服务端部署在自己的服务器上,比如群晖的 Docker 中。但官方的 Docker 镜像要求至少 2G 以上内存,对系统要求比较高。有人用 Rust 实现了 Bitwarden 服务器,项目叫 bitwarden_rs,并且提供了 Docker 镜像,这个实现更进一步降低了对机器配置的要求,并且 Docker 镜像体积很小,部署非常方便。

Bitwarden 的缺点:

  • 不能离线编辑
  • 客户端不能自动同步
  • 不能自动点击登录按钮

相比较,1Passwords 更为方便。

确认你的环境

首先你得有:

  • 支持 Docker 的群晖

如果你只是打算在内网中使用 Bitwarden,有群晖就可以了。如果你希望随时随地可以访问群晖上搭建的 Bitwarden 服务,你还需要以下东西:

  • 宽带(是否公网 IP 都可以)
  • 自己的域名(本教程以域名 b.penpenguanguan.com 为例)
  • 域名证书(可选)

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

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

关于免费的域名证书及有效期:

如果你使用二级域名访问 Bitwarden 服务器,则你需要有此二级域名的证书或顶级域名的泛域名证书。而阿里云或 dnspod 不能申请免费的泛域名证书,常见的 Let’s Encrypt 免费泛域名证书有效期只有三个月,实际用在 Bitwarden 服务端上并不方便(因为你得每三个月手动更换一次证书文件),所以你需要为此二级域名单独申请一个免费的证书。

搭建 Bitwarden 服务端

如果你不启用 SSL 或只是打算在内网中使用 Bitwarden,那下面操作中与证书、SSL 相关的步骤可以忽略。

准备工作

群晖上安装 Docker

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

群晖中分别新建用于存放数据文件和证书文件的文件夹

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

将证书文件放置于 docker/bitwarden/ssl 目录

解压之前下载好的证书文件压缩包,将 Nginx 文件夹下的 xxx.crtxxx.key 两个文件放入 docker/bitwarden/ssl 目录。当然你也可以将这两个文件重命名,包括后缀。(这里以文件名 sslcert.crt 和 sslkey.key 为例)

不要使用除 Nginx 文件夹下的其他证书文件,因为其他证书文件不包含中间证书,会导致安卓版的 Bitwarden 客户端无法登陆。

关于证书文件的说明:

  1. xxx.crt 和 xxx.key 文件可以随意重命名,甚至使用任意的扩展名。虽然网上很多教程使用的是.pem 的扩展名
  2. xxx.crt 文件如果不包含中间证书信息,对除安卓以为的客户端不受影响
  3. 如果你使用不带中间证书的证书文件,又希望你的安卓客户端能正常使用,解决方法就是把中间证书安装到你的安卓手机上。安装方法见后文。

Docker 里安装并配置 Bitwarden

下载 Bitwarden 镜像

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

配置容器参数

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

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

添加证书文件的存储路径:“卷” 中添加 “文件夹路径”docker/bitwarden/ssl(根据你建的文件夹的路径修改);“装载路径”/ssl/(不能修改)

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

启用 SSL:添加环境变量 ROCKET_TLS,值 {certs="/ssl/sslcert.crt",key="/ssl/sslkey.key"}

此为可选项,为了安全,强烈建议启用。

其他按照默认

启动 Bitwarden 容器后,浏览器输入 https://群晖的 ip:8080(不启用 SSL 则为:http://群晖的 ip:8080),应该就可以进入登录页面了。

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

设置外网访问 Bitwarden 服务端

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

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

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

现在新装宽带一般都不是公网 IP 了,如果是电信宽带可以打客服电话要求给公网 IP,实在不行工信部;移动宽带的话不用想了;联通宽带不清楚。

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

有公网 IP

先在你内网的任一台机器(路由器或者群晖等)设置好 DDNS 服务,当然你如果是固定的公网 IP 就不需要设置 DDNS。DDNS 的设置方法这里就不写步骤了,网上有很多教程。

然后在路由器上设置端口转发:外网的 28080 端口(你自己定义)转发到内网群晖 IP 地址的 8080 端口。

无公网 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 = 8080 # 映射到 NAS 上的本地端口
remote_port = 28080 # 远程访问端口,你自己定义

搭建完成

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

浏览器:使用 https://b.penpenguanguan.com:28080

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

简化域名地址

这里说的简化域名地址,就是使用不带端口号的域名地址,其实是利用 https 默认的 443 端口。简化的地址也更好记,比如用 https://b.penpenguanguan.com 替代 https://b.penpenguanguan.com:28080 访问 Bitwarden 服务器。(个人建议使用域名+端口的方式,复杂的地址更安全)

同样,根据你的宽带是否有公网 IP,设置方式不一样。

有公网 IP

家庭宽带一般都封锁了 80 端口,但基本都没有封锁 https 的 443 端口。

所以我们仅需要在路由器上设置端口转发即可:外网的 443 端口转发到内网群晖 IP 地址的 8080 端口。

这样你的访问地址就变成 https://b.penpenguanguan.com 了。

网上很多教程说的是在群晖中设置反向代理,或者路由器上做端口转发到群晖的 443 端口,再在群晖中设置反向代理,其实这种情况并不需要在群晖中设置反向代理。

无公网 IP

待更新

群晖有公网 IP

前面的内容基于你的群晖处于局域网的环境拥有的是局域网 IP 地址,如果你的群晖有公网 IP 地址(IPv4 或 IPv6),简化域名就需要利用群晖的反向代理功能了。使用群晖的反向代理后,Bitwarden 环境变量中就不需要启用 SSL 了。

同样,如果是动态 IPv4 或 IPv6 地址,需要先设置 DDNS。

简化域名的设置步骤如下:

1、进入群晖的 “控制面板”-“Synology 应用程序门户”-“反向代理服务器”,如图添加一条 “反向代理服务器规则”

2、进入群晖的 “控制面板”-“安全性-“证书”,将你的域名证书导入群晖中,并配置刚才添加的反向代理服务器规则使用此证书

3、完成

IPv6 现在已经比较普及,电信移动联通的手机基本都能获取到 IPv6 地址,宽带也可以使用 IPv6 地址了。处于局域网环境的群晖也可以获取公网 IPv6 地址了。

群晖获取 IPv6 地址的方法:首先光猫上开启 IPv6,然后路由器开启 IPv6,具体的设置方法这里就不写步骤了,网上有很多教程。

IPv6 的 DDNS 的设置方法目前网络上的资料比较少,群晖自带的 DDNS 对 IPv6 支持也不是很稳定。观察了几天,我的移动宽带下的群晖获取到的 IPv6 地址一直是固定的,所以就直接解析了。但目前 IPv6 未完全普及,各软件在 IPv6 下不是很稳定,遂放弃了使用 IPv6。

进阶用法

使用多个域名访问 Bitwarden 服务端

利用群晖的反向代理功能,我们可以设置使用多个域名来访问 Bitwarden 服务端。

大致的步骤:

  1. 每个域名的证书导入群晖中
  2. Bitwarden 服务端关闭 SSL
  3. 每个域名在群晖中设置一条反向代理服务器规则
  4. 设置每条反向代理服务器规则使用相应的证书

增加 Bitwarden 功能

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

先来说一下如我这种对 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 日志记录

添加环境变量 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 等更多高级功能。

进入管理页面后有一段需要注意的文字:

NOTE: The settings here override the environment variables. Once saved, it’s recommended to stop setting them to avoid confusion. This does not apply to the read-only section, which can only be set through the environment.(注意:此处的设置将覆盖环境变量。 保存后,建议停止设置以免造成混淆。 这不适用于只读部分,该部分只能通过环境进行设置。)

我认为个人用户不太需要这个管理功能,倒是适合企业用户。个人用户需要增加功能的话,建议通过添加环境变量的方式。

故障及解决

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 wikiEnabling 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 [email protected]
  • 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. PC 客户端或 Web 端里 “导出密码库”
  2. 备份 data 数据文件目录

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

mprasil/bitwarden 切换为 bitwardenrs/server

如果你使用的旧版镜像是mprasil/bitwarden,想切换为新版镜像bitwardenrs/server,先备份 data 数据文件目录和 ssl 证书文件目录,删除旧容器下载新版镜像,然后重新配置即可。

两个镜像使用同样的配置方式,原有的数据文件可以无损切换。但是强烈建议切换之前通过 PC 客户端或 Web 端导出你的密码库。

Bitwarden 服务端容器更新方法

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

PC 客户端 Bug

PC 客户端版本:1.16.6。即使 Bitwarden 服务端容器已停止,也会提示 “同步完成”

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

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

参考链接

已有 11 人 对 ”使用群晖自建 Bitwarden 密码服务器” 进行了评论

  1. dd说道:

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

    • 王小喜说道:

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

  2. jason说道:

    想问个问题,有没有管理员用户可以删除建立的账户呢

    • 王小喜说道:

      当然可以,Enabling admin page

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

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

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

  3. 阿锐说道:

    请问一下自己在群辉上建的可以使用两步认证的功能吗

  4. Stride说道:

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

    • 王小喜说道:

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

  5. 小贝说道:

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

    • test说道:

      可能是 IOS 禁止不安全网络连接吧,部署 https 试一下

    • 王小喜说道:

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

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

王小喜 发表评论





7 + 4 = ?

注意:
1、请勿单纯发表顶啊、打酱油之类无任何意义的评论,否则将被视为spam!谢谢合作!
2、但欢迎你留下对本文的看法或技术上的任何疑问,我会及时回复你。