2.使用 Let's Encrypt 证书运行私有 Vaultwarden 实例
对应的官方页面地址
假设您希望运行一个只能从本地网络访问的 Vaultwarden 实例,但您又希望此实例启用由一个被广泛接受的 CA 而不是你自己的私有 CA 来签署的 HTTPS(以避免将专用 CA 证书加载到所有设备中的麻烦)。
本文将演示如何使用 Caddy Web 服务器创建这样的设置,Caddy 内置了对诸多 DNS 提供商的 ACME 支持。我们将通过 ACME DNS 验证方式获取 Let's Encrypt 证书来配置 Caddy -- 在这里使用通常的 HTTP 验证方式的话会有问题,因为它依赖于 Let's Encrypt 服务器能够访问到您的内部 Web 服务器。
本文涵盖了更通用的 DNS 验证设置,但许多用户可能会发现使用 Docker Compose 来集成 Caddy 和 Vaultwarden 是最简单的。具体的例子请参见使用 Docker Compose。
涵盖了两个 DNS 提供商:
Duck DNS -- 为你提供一个
duckdns.org
下的子域名(例如my-bwrs.duckdns.org
)。如果您没有自己的域名,此选项是最简单的。Cloudflare -- 这可以让您把您的 Vaultwarden 实例放在您拥有或控制的域名下。请注意,Cloudflare 可以只作为一个 DNS 提供商使用(即不使用 Cloudflare 最著名的代理功能)。如果您目前没有自己的域名,您也许可以在 Freenom 获得一个免费的域名。
当然也可以使用其他的网络服务器、ACME 客户端和 DNS 提供商的组合来创建类似的设置,但您必须解决细节上的差异。
获取自定义 Caddy 构建
由于大多数人不使用 DNS 验证方式,为每个 DNS 提供商自定义实现,因此 Caddy 默认没有内置此验证方式的支持。
最简单的方式是通过 https://caddyserver.com/download 获取带有 DNS 验证模块的 Caddy 版本。选择您的平台,选中 github.com/caddy-dns/cloudflare
(用于 Cloudflare)和/或 github.com/caddy-dns/duckdns
(用于 Duck DNS),然后点击下载。
如果您喜欢从源代码构建,可以使用 xcaddy
。例如,要创建一个包含 Cloudflare 和 Duck DNS 支持的构建:
将 caddy
二进制 移动到 /usr/local/bin/caddy
或其他合适的目录中。使文件可执行。(可选)运行语句 sudo setcap cap_net_bind_service=+ep /usr/local/bin/caddy
以允许 caddy
在特权端口 (< 1024) 上监听,而无须以 root 身份运行。
Duck DNS 设置
如果您还没有账户,请在 https://www.duckdns.org/ 创建一个。给您的 Vaultwarden 实例创建一个子域名(例如,my-vw.duckdns.org
),将其 IP 地址设置为您的 Vaultwarden 主机的私有 IP(例如,192.168.1.100)。记下您的账户的 token 值(UUID 格式的字符串)。Caddy 将需要此 token 来完成 DNS 验证。
在 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
:
在设置 Caddy 之前,Vaultwarden 是否已运行并不重要。
您现在应该可以通过 https://my-vw.duckdns.org
访问到您的 Vaultwarden 实例了。如果没有,请检查 caddy 的输出。
您可以使用 [STRG]-[C] 来停止 caddy。接下来通过以下命令在后台启动 caddy:
重要提示:如有必要,在某些路由器(例如 FritzBox)或 DNS 解析器(例如 unbound)中,由于 DNS 重新绑定保护,必须为域名(例如 my-vw.example.com
)设置例外。
Cloudflare 设置
如果您还没有账户,请在 https://www.cloudflare.com/ 创建一个;您还需要到您的域名注册商那里将名称服务器设置为 Cloudflare 分配给您的值。为您的 Vaultwarden 实例创建一个子域名(例如,vw.example.com
),将其 IP 地址设置为您的 Vaultwarden 主机的私有 IP(例如,192.168.1.100
)。例如:
创建一个用于 DNS 验证的 API token(更多背景知识,请参阅 https://github.com/libdns/cloudflare/blob/master/README.md):
点击右上角的个人图标并导航到
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 获取证书
lego
CLI 获取证书在上面的 DuckDNS 例子中,Caddy 使用 lego
库通过 DNS 验证获取证书。lego
也有一个 CLI,你可以直接使用它来获取证书,例如,如果你想使用 Caddy 以外的反向代理。 (注意:这个例子使用 lego
,但也有其他独立的 ACME 客户端支持 DNS 验证方式(参阅 DNS 验证部分)。
下面是一个如何做到这一点的例子。
从 https://github.com/go-acme/lego/releases 下载预建的
lego
二进制文件到您的系统中。将其解压到某个目录,比如/usr/local/lego
。从那个目录中,运行
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
。这将在你的证书即将到期时更新它。
lego
默认请求 ECC/ECDSA 证书。如果您使用 Vaultwarden 中内置的 Rocket HTTPS 服务器,您需要请求 RSA 证书。在上面的 lego
命令中,添加选项 --key-type rsa2048
。
在这个例子中,您需要用生成的输出来配置您的反向代理:
/usr/local/lego/.lego/certificates/my-vw.duckdns.org.crt
(证书)/usr/local/lego/.lego/certificates/my-vw.duckdns.org.key
(私钥)
故障排除
DNS 问题
如果您的子域名出现 DNS 解析错误(例如,DNS_PROBE_FINISHED_NXDOMAIN
或 ERR_NAME_NOT_RESOLVED
),可能是您的 DNS 解析器阻止了解析,有以下原因:
出于安全原因,它会阻止动态 DNS 服务。
为防止 DNS 重新绑定攻击,或出于其他一些原因,它会阻止域名解析到私有 (RFC 1918) IP 地址。
无论哪种情况,您都可以尝试使用其他 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 的环境文件:
参考
DNS 验证
Caddy Cloudflare 组件
Caddy Duck DNS 组件
最后更新于