前言

最近发现 navi.seanzou.com 突然没有自动更新了Let's Encrypt的 SSL证书了,很神奇,于是乎来检查一下。

发现原因原来是,Nginx强制从HTTP 跳转 HTTPS,然后由于没有更新的时候已经没有证书了只剩下HTTP的访问,然后导致了强制访问HTTPS失败,然后一直更新失败这样的结果。

正文

1. 主要问题

navi.seanzou.com: Invalid status. Verification error details: 47.241.94.225: Invalid response from https://navi.seanzou.com/.well-known/acme-challenge/MCJlTg4J3i4wFMj3ZnMGza4zX67Y4hLT5av1gjKmI7s: 404

问题就是,命令行的回应404。然后打开 /usr/local/nginx/conf/vhost/wordpress.conf 发现如下:

server{
  listen 80;
  listen [::]:80;
  server_name navi.seanzou.com;
  rewrite ^ https://$host$request_uri? permanent;
}

得,强制转换,这样如果HTTPS收不到的情况下,强制访问肯定访问不到的。

2. 解决办法:让 80 端口对 ACME 留个“后门”

思路是:

  • 80 端口依然可以跳 https(SEO/安全都没问题)

  • 但要给 /.well-known/acme-challenge/ 留一个不重定向的口子,让 acme.sh 能在这里放校验文件、Let’s Encrypt 能直接用 HTTP 访问到。

把rewrite放到 location / 里面,把 80 端口的 server 改成这样:

server{
  listen 80;
  listen [::]:80;
  server_name navi.seanzou.com;

  # 注意:不要在 server 顶层写 rewrite 了

  location / {
    # 这里再做 80 -> 443 的重定向
    rewrite ^ https://$host$request_uri? permanent;
  }
}

这是由于,acme.sh 在 --nginx 模式下,会自动往这个 server 里加一个类似:

location ^~ /.well-known/acme-challenge/ {
    alias /root/.acme.sh/navi.seanzou.com_ecc/.well-known/acme-challenge/;
}

而在Nginx 的 location 匹配规则里,location ^~ /.well-known/acme-challenge/ 的优先级比 location / 高,所以:

  • 访问 /.well-known/acme-challenge/... → 命中 acme 的 location,不会走 rewrite,Let’s Encrypt 能拿到校验文件

  • 访问其它路径 → 走 location / → 301 跳 https

成功!

[Fri Nov 28 09:50:18 CST 2025] Reloading nginx
[Fri Nov 28 09:50:21 CST 2025] Pending. The CA is processing your order, please wait. (1/30)
[Fri Nov 28 09:50:25 CST 2025] Pending. The CA is processing your order, please wait. (2/30)
[Fri Nov 28 09:50:29 CST 2025] Pending. The CA is processing your order, please wait. (3/30)
[Fri Nov 28 09:50:32 CST 2025] Pending. The CA is processing your order, please wait. (4/30)
[Fri Nov 28 09:50:36 CST 2025] Success

总结

配置acme.sh 和 Let's Encrypt 的时候,记得nginx的配置呀!

很重要嘟!

参考

[1] 自己
[2] ChatGPT

立志做一个有趣的碳水化合物。