前两天突然发现博客 HTTPS 证书过期无法访问了,由于只设置了 HTTPS,证书过期后连 HTTP 链接也无法访问了,需要紧急处理一下。

博客站点的证书是由 acme.sh 申请安装的,按道理应该能够自动更新才对,怀疑是更新机制出现了什么问题。

问题排查解决.

首先尝试手动更新证书:

acme.sh --renew -d liming.me --force

注意:-d 是当时创建证书时定的名字,不是站点的域名

发现更新程序一直显示超时:

Processing, The CA is processing your order, please just wait. (29/30)
liming.me:Timeout

怀疑是无法访问证书提供商 https://acme.zerossl.com/v2/DV90

在网上查阅了相关的资料发现也有遇到相同问题的:Issue #3995 · acmesh-official/acme.sh

文中给出的方案是尝试切换到另一个证书提供方 lets encrypt:

acme.sh --set-default-ca --server letsencrypt

配置好之后再次尝试更新,发现依旧是超时。

开始怀疑不是证书提供方的问题,而是服务器的配置问题。

接着开始尝试重新申请一个新的证书:

acme.sh --install-cert -d liming.me --key-file /usr/local/nginx/key.pem --fullchain-file /usr/local/nginx/cert.pem --reloadcmd "service nginx force-reload"

同样无法成功,不过这次找到了报错的根本问题:

Pending, The CA is processing your order, please just wait. (1/30)
liming.me:Verify error:Invalid response from https://liming.me/.well-known/acme-challenge/y52dreZzMrl4XJ807n0sazxOJnd2Vd1W22X3NcqDT1g [xxx.xxx.xxx.xxx]:

这次错误显示是无法从服务器返回,导致验证失败。

从这个报错信息可以看到一个细节,那就是证书提供方在验证服务的时候访问的是 https 的链接,但我现在的服务的 https 证书已经过期了,这个链接肯定是访问不通的。

但是为什么对方会访问到 https 的链接呢,按道理 acme 不应该有这种问题。

由于执行命令是增加了参数 – log 可以进到日志中查看更详细的信息,然后就发现了关键点:

_start_tag='        rewrite ^(.*)$ https://liming.me$1 permanent;'

acme.sh 在申请证书是会备份并修改原本的 nginx 配置文件,增加验证的路由信息,但我原本的配置中有一条强制跳转 https 的配置。

猜测就是这条配置导致了证书提供方在验证的时候被强制重定向到了 https 上的链接,导致验证失败。更新的时候也是一样的问题。

果然,在去掉这行配置之后,证书就能够正常更新了。

Processing, The CA is processing your order, please just wait. (1/30)
Success