L30110
2021 年12 月 24 日 18:20
1
几个月前(具体时间不清楚,但至少有几个月了),我的 Discourse 论坛上的 Let’s Encrypt 续订开始失败,尽管之前已经正常运行了很多年。几天前我注意到这个问题时,证书已于 2021 年 8 月过期。在尝试手动续订和重启 nginx 后,我发现证书的过期日期被推迟到几天前。显然,这仍然不是一个当前证书。在 discourse 容器内手动运行 acme.sh 强制续订时,我遇到了这个错误(其中 [site] 当然是我的网站地址):
[site]:Verify error:Fetching http://[site]/.well-known/acme-challenge/[long alpha challenge string]: Error getting validation data
我应该注意的是,该网站要求所有用户访问都需要登录,但这在过去几年中对 SSL 证书续订一直不是问题。
有什么想法吗?非常感谢!
更新:使用 wget 测试验证会返回 404。但是,我不知道这些数据是如何在容器中的 nginx 中为 Discourse 配置的,以及它与代理在容器外部的 nginx 有何关系。
2 个赞
L30110
2021 年12 月 24 日 18:35
3
您好。这不应该有关联,因为该问题会导致浏览器因不同的错误而拒绝证书,而不是像我遇到的那样出现过期错误。看起来 Let’s Encrypt 突然无法与 Discourse 进行身份验证以提供新证书。谢谢。
2 个赞
RGJ
(Richard - Communiteq)
2021 年12 月 24 日 20:18
4
JammyDodger:
如果它是在几个月前,是否与此有关:
如果第一次到期是在八月份,那就不是了。它应该在那之后续期。
4 个赞
Benjamin_D
(Benjamin Decotte)
2021 年12 月 24 日 20:55
5
2 个赞
L30110
2021 年12 月 24 日 21:27
6
您好。这些似乎不适用。我看到的是 404 错误,而不是那些其他错误,构建一直都在更新,而且 GitHub 上的那个模板确实是我安装中已安装的版本。谢谢!
3 个赞
pfaffman
(Jay Pfaffman)
2021 年12 月 24 日 23:39
7
您在使用 Cloudflare(橙色云)还是其他反向代理?
2 个赞
L30110
2021 年12 月 24 日 23:51
8
否。在 Ubuntu 18.04 上本地托管,使用默认的 Docker 安装。
3 个赞
L30110
2021 年12 月 25 日 00:39
9
在容器中手动运行 cron 作业进行证书续订时,失败情况始终相同。尝试获取:
http://[site]/.well-known/acme-challenge/[challenge-string]
因“获取验证数据时出错”而失败。
2 个赞
由于不熟悉该流程,它是否期望容器处于运行该脚本时并非如此的状态?例如,也许它期望另一个 cron 作业首先发生,该作业准备 nginx 以允许访问此类 URL。
您是否尝试过重建?(这将尝试在此过程中获取新证书。)
您提到它托管在本地。您是否能够使用域名从网络外部访问该实例?
2 个赞
L30110
2021 年12 月 25 日 00:56
11
您好,是的,多次 重建。没有变化。我在许多非 Discourse 网站上使用 Let’s Encrypt,它们都能正常续订。是的,我可以从外部网站访问,并且我已使用 wget 测试过,结果是 404。问题是:在这种情况下,nginx html 树的确切位置 在哪里,也就是包含(或应该包含).well-known 目录的部分?我一直找不到。谢谢。
2 个赞
我找不到 cron 作业,只有一个位于 /etc/runit/1.d/letsencrypt 的 runlevel 脚本。看起来该脚本会启动一个新实例的 nginx,其配置包括:
location ~ /.well-known {
root /var/www/discourse/public;
allow all;
}
我认为这意味着路径最终会是 /var/www/discourse/public/acme-challenge,尽管它可能在挑战之前被创建,然后在之后被删除。
如果你尝试手动运行的脚本是那个,你是否先停止了 nginx?脚本尝试启动的实例会尝试监听端口 80,所以我怀疑如果 nginx 已经为 Discourse 运行,那会失败。
2 个赞
L30110
2021 年12 月 25 日 01:33
13
我认为我可能看到了问题所在。但我不知道如何解决它。看起来所有对https端口80上的论坛的访问尝试(正如预期的那样)都被重定向到了https端口443。对。但这导致Let’s Encrypt在尝试续订验证时失败,因为当前证书已过期。我可以用wget看到重定向。那么问题来了,我该如何暂时禁用重定向,以便Let’s Encrypt能够验证并为我获取新的未过期证书?一个可能的额外复杂情况是,重定向是301永久重定向。谢谢。
2 个赞
此重定向位于 /etc/nginx/conf.d/discourse.conf 中,在 nginx 停止然后使用我之前帖子中提到的配置启动时将不会使用。
恐怕我对自动升级的工作方式不太熟悉,因此不确定在容器运行时续订的合适方法是什么。理论上,只需停止并启动容器就应该可以续订,但既然您说重建没有做到这一点,那可能也不会。
acme.sh 有 --renew-all 等选项,但不确定它需要哪些其他选项才能在此处正确执行。以下内容可能就是您所需要的,但我无法确定。
LE_WORKING_DIR="/shared/letsencrypt" /root/acme.sh/acme.sh --renew-all
2 个赞
L30110
2021 年12 月 25 日 02:52
15
这确实允许 Let’s Encrypt 在没有重定向的情况下进行访问,但它正在查找的文件似乎不存在,因此最终验证仍然失败。
2 个赞
mbronstein
(Mark Bronstein)
2021 年12 月 27 日 16:51
16
我遇到了同样的问题。有人找到解决此问题的明确步骤吗?
2 个赞
L30110
2021 年12 月 27 日 17:06
17
我正在尝试使用此命令成功获取证书。看起来 curl 确实检索到了验证令牌,但 acme.sh 每次仍然声明验证失败!所以仍然无法访问。
“/shared/letsencrypt”/acme.sh --renew-all --force --insecure --home “/shared/letsencrypt” --debug
2 个赞
griffin
(Jonathan Griffin)
2021 年12 月 27 日 20:11
18
您好 @L30110
我是 Let’s Encrypt 社区 的常客 griffin 。@JimPas 让我来查看这个帖子,我会在午餐回来后立即处理。
3 个赞
griffin
(Jonathan Griffin)
2021 年12 月 27 日 22:24
19
对于许多 ACME 客户端(例如 acme.sh),当 nginx 被指定为身份验证方法时,http-01 挑战 文件会根据 nginx 服务器配置中的异常/重定向创建一个特定目录,而不是直接创建在 webroot 目录的 .well-known/acme-challenge 目录结构中。通常,这种重定向仅在挑战验证期间临时存在,挑战文件本身也是如此。
因此:
这是一个明智的考虑。一个编写良好的续订脚本应该不需要停止 nginx。通常,nginx 用于提供挑战文件,然后使用类似 nginx -s reload 的命令在获取新证书后优雅地重新加载 Web 服务器/代理。
不。
根据 Challenge Types - Let's Encrypt
我们对 HTTP-01 挑战的实现遵循重定向,最多 10 次重定向。它只接受到“http:”或“https:”的重定向,并且只接受到端口 80 或 443 的重定向。它不接受到 IP 地址的重定向。当重定向到 HTTPS URL 时,它不会验证证书(因为此挑战旨在引导有效的证书,它可能会遇到自签名或过期的证书)。
通常,当我们遇到此类问题时,通常是以下原因之一:
防火墙未允许流量通过到提供挑战文件的 Web 服务器/代理。
路由器/代理映射/配置不正确,导致 Boulder(Let’s Encrypt CA 服务器)的挑战验证请求尝试从错误的 Web 服务器或目录检索文件。
某种重写/重定向(例如 Apache 中的 .htaccess 文件)干扰了 Web 服务器/代理从正确位置提供挑战文件的能力。
使用非标准端口,通常伴随不正确的映射。
运行 ACME 客户端的容器将挑战文件创建在 Web 服务器/代理(例如 nginx)未提供它们的目录中。当涉及 Docker 时,这几乎总是问题所在。
2 个赞
L30110
2021 年12 月 27 日 23:04
20
您好。您列出的各种项目中有几项显然不适用于我的情况。不是防火墙问题——我可以使用 wget 或 curl 从以下所有位置手动访问令牌:1) Docker Discourse 应用程序内部,2) 从 Docker 容器外部的主机系统,以及 3) 一个相关的系统。
对于这些手动情况,假设指定了 --ignore 或 -k 以绕过 Discourse 自动重定向到 https 时的过期证书,我确实从预期的位置获取了令牌内容。
我没有更改 Discourse 在 Discourse Docker 容器内部或外部创建的任何 nginx 配置。我没有运行任何 nginx 副本,Apache 也仅在本地使用完全不同的端口。请注意,这一切已经正常运行了两年多,有定期的证书续订,并且没有其他应用程序更改——这是一个非常稳定的盒子。
没有不寻常的端口。
由于我可以手动获取令牌内容,因此我认为错误的位置不会有问题。除非……
我在测试时没有手动停止 nginx。我现在已经这样做了,但没有明显区别——acme.sh 仍然出现相同的错误(目前又是错误 56)。当从容器内部停止 nginx 时,我确实在主机上看到了一个 runsv nginx 实例,但它没有工作进程或缓存进程。当我重新启动容器内的 nginx 时,工作进程和缓存进程会与仍然存在的 runsv nginx 一起出现在主机上。容器内的 sv start/stop nginx 命令会按预期确认这些操作。
但上面提到的还有其他可能令人担忧的事情。而且我不明白为什么在事情已经正常工作了这么长时间后,这会突然成为一个问题。
由于 ISP 提供静态 IP 地址的复杂性,论坛的静态 IP 地址(从我的本地网络外部使用)无法由该机器 用于连接到该机器自身的服务。我通常会使用 /etc/hosts 中的条目为这些名称提供本地网络 IP 地址。因此,当我使用同一台机器(容器内部或外部,它们都有针对论坛的 /etc/hosts 添加项)上的 curl 进行测试时,测试使用的是与外部站点通过 DNS 查询时使用的 IP 地址不同的(本地)IP 地址。这是否可能相关?谢谢。
2 个赞