2.使用 Let's Encrypt 证书运行私有 Vaultwarden 实例
最后更新于
最后更新于
对应的
假设您希望运行一个只能从本地网络访问的 Vaultwarden 实例,但您又希望此实例启用由一个被广泛接受的 CA 而不是你自己的 来签署的 HTTPS(以避免将专用 CA 证书加载到所有设备中的麻烦)。
本文将演示如何使用 Web 服务器创建这样的设置,Caddy 内置了对诸多 DNS 提供商的 ACME 支持。我们将通过 ACME 获取 Let's Encrypt 证书来配置 Caddy -- 在这里使用通常的 HTTP 验证方式的话会有问题,因为它依赖于 Let's Encrypt 服务器能够访问到您的内部 Web 服务器。
本文涵盖了更通用的 DNS 验证设置,但许多用户可能会发现使用 Docker Compose 来集成 Caddy 和 Vaultwarden 是最简单的。具体的例子请参见。
涵盖了两个 DNS 提供商:
-- 为你提供一个 duckdns.org
下的子域名(例如 my-bwrs.duckdns.org
)。如果您没有自己的域名,此选项是最简单的。
-- 这可以让您把您的 Vaultwarden 实例放在您拥有或控制的域名下。请注意,Cloudflare 可以只作为一个 DNS 提供商使用(即不使用 Cloudflare 最著名的代理功能)。如果您目前没有自己的域名,您也许可以在 获得一个免费的域名。
当然也可以使用其他的网络服务器、和 DNS 提供商的组合来创建类似的设置,但您必须解决细节上的差异。
由于大多数人不使用 DNS 验证方式,为每个 DNS 提供商自定义实现,因此 Caddy 默认没有内置此验证方式的支持。
最简单的方式是通过 获取带有 DNS 验证模块的 Caddy 版本。选择您的平台,选中 github.com/caddy-dns/cloudflare
(用于 Cloudflare)和/或 github.com/caddy-dns/duckdns
(用于 Duck DNS),然后点击下载。
如果您喜欢从源代码构建,可以使用 。例如,要创建一个包含 Cloudflare 和 Duck DNS 支持的构建:
将 caddy
二进制 移动到 /usr/local/bin/caddy
或其他合适的目录中。使文件可执行。(可选)运行语句 sudo setcap cap_net_bind_service=+ep /usr/local/bin/caddy
以允许 caddy
在特权端口 (< 1024) 上监听,而无须以 root 身份运行。
在 caddy 可执行文件所在的同一目录中创建一个名为 Caddyfile
(大写 C,无文件扩展名)的文件,其中包含以下内容,并将 localhost:
端口替换为 Vaultwarden 在其 ROCKET_PORT=
指令中使用的端口(Vaultwarden 的默认 Rocket_port 为 8001):
创建一个名为 caddy.env
的文件,内容如下(替换相应的值):
切换到 caddy 所在目录然后运行以下命令以首次启动 caddy
:
Duck DNS 域名(例如 my-vw.duckns.org)的 caddy 首次启动需要几秒钟的时间来解决 DNS 挑战和获取 HTTPS 证书。Caddy 通常将它们存储在 /root/.local/share/caddy
中,以及 caddy 的配置会自动保存到 /root/.config/caddy
。
运行命令以启动 vaultwarden
:
您现在应该可以通过 https://my-vw.duckdns.org
访问到您的 Vaultwarden 实例了。如果没有,请检查 caddy 的输出。
您可以使用 [STRG]-[C] 来停止 caddy。接下来通过以下命令在后台启动 caddy:
重要提示:如有必要,在某些路由器(例如 FritzBox)或 DNS 解析器(例如 unbound)中,由于 DNS 重新绑定保护,必须为域名(例如 my-vw.example.com
)设置例外。
点击右上角的个人图标并导航到 My Profile
,然后选择 API Tokens
选项卡。
点击 Create Token
按钮,然后点击Edit zone DNS
右边的 Use template
。
编辑 Token name
字段(如果您希望使用更具描述性的名称)。
在 Permissions
下应出现一个权限:Zone / DNS / Edit
。添加其他权限:Zone / Zone / Read
。
在 Zone Resources
下,设置 Include / Specific zone / example.com
(使用您自己的域名替换 example.com
)。
在 TTL
下,为您的 tokan 设置一个变为非活动状态的 End Date。您也可以在以后设置。
创建 token 并复制 token 值。
您的 token 列表看起来应该像这样:
创建一个名为 Caddyfile
的文件,内容如下:
创建一个名为 caddy.env
的文件,内容如下(替换相应的值):
运行命令以启动 caddy
:
运行命令以启动 vaultwarden
:
您现在应该可以通过 https://vw.example.com
访问到您的实例了。
重要提示:如有必要,在某些路由器(例如 FritzBox)中,由于 DNS 重新绑定保护,必须为域名(例如 vw.example.com
)设置例外。
lego
CLI 获取证书下面是一个如何做到这一点的例子。
从那个目录中,运行 DUCKDNS_TOKEN=<token> ./lego -a --dns duckdns -d my-vm.duckdns.org -m me@example.com run
(用合适的值替换令牌、域名和电子邮件地址)。这将使您在 Let's Encrypt 注册,并为您的域名获取一个证书。
设置一个每周的 cron 作业来运行 DUCKDNS_TOKEN=<token> ./lego --dns duckdns -d my-vw.duckdns.org -m me@example.com renew
。这将在你的证书即将到期时更新它。
在这个例子中,您需要用生成的输出来配置您的反向代理:
/usr/local/lego/.lego/certificates/my-vw.duckdns.org.crt
(证书)
/usr/local/lego/.lego/certificates/my-vw.duckdns.org.key
(私钥)
如果您的子域名出现 DNS 解析错误(例如,DNS_PROBE_FINISHED_NXDOMAIN
或 ERR_NAME_NOT_RESOLVED
),可能是您的 DNS 解析器阻止了解析,有以下原因:
出于安全原因,它会阻止动态 DNS 服务。
无论哪种情况,您都可以尝试使用其他 DNS 解析器,例如 Google 的 8.8.8.8
或 Cloudflare 的 1.1.1.1
。对于第二种情况,如果您在 dnsmasq 或 Unbound 等本地 DNS 服务器后面运行,则可以将其配置为完全禁用 DNS 重新绑定保护,或允许某些域名返回私有地址。关于 Unbound,您可以通过将以下指令添加到其配置文件中来实现(使用您自己的 Duck DNS 域名替换该域名):
然后通过 unbound-control reload
或 systemctl restart unbound
重新启动 unbound 以使其加载新配置。
此外,请确保关闭您之前为 Vaultwarden 设置的 HTTPS 设置,特别是通过 Rocket TLS 使用您自己的(自签名)证书的私有 CA,因为这会干扰您新的 Let's Encrypt 受保护的域名。只需在 Vaultwarden 的环境文件中注释掉(# 符号)ROCKET_TLS
指令即可:
更改域名后不要忘记更新 Vaultwarden 的环境文件:
如果您还没有账户,请在 创建一个。给您的 Vaultwarden 实例创建一个子域名(例如,my-vw.duckdns.org
),将其 IP 地址设置为您的 Vaultwarden 主机的私有 IP(例如,192.168.1.100)。记下您的账户的 token 值( 格式的字符串)。Caddy 将需要此 token 来完成 DNS 验证。
如果您还没有账户,请在 创建一个;您还需要到您的域名注册商那里将名称服务器设置为 Cloudflare 分配给您的值。为您的 Vaultwarden 实例创建一个子域名(例如,vw.example.com
),将其 IP 地址设置为您的 Vaultwarden 主机的私有 IP(例如,192.168.1.100
)。例如:
创建一个用于 DNS 验证的 API token(更多背景知识,请参阅 ):
在上面的 DuckDNS 例子中,Caddy 使用 lego
库通过 DNS 验证获取证书。lego
也有一个 CLI,你可以直接使用它来获取证书,例如,如果你想使用 Caddy 以外的反向代理。 (注意:这个例子使用 lego
,但也有其他独立的 ACME 客户端支持 DNS 验证方式(参阅 部分)。
从 下载预建的 lego
二进制文件到您的系统中。将其解压到某个目录,比如 /usr/local/lego
。
lego
默认请求 ECC/ECDSA 证书。如果您使用 Vaultwarden 中内置的 ,您需要请求 RSA 证书。在上面的 lego
命令中,添加选项 --key-type rsa2048
。
为防止 攻击,或出于其他一些原因,它会阻止域名解析到私有 (RFC 1918) IP 地址。