站点 2026 年 9 月把 DNS 切到 Cloudflare,代理开关打开后 Let’s Encrypt 的 60 天续签开始报 Invalid response from /.well-known/acme-challenge/xxx: 404,源站文件确实存在,certbot 每次都在 DNS 验证前放弃。
把日志和配置对完,能解释这个现象的基本就这几处。代理模式把 acme-challenge 也走了 CDN,边缘节点缓存了上一次 404 的空响应;缓存规则里没有把这个前缀排除,TTL 默认按 4 小时算;源站 Nginx 对以点开头的目录返回 403,CDN 把 403 一起缓存下来。
上来先看该路径在各节点返回的状态
curl -sI https://www.example.com/.well-known/acme-challenge/test | head -5
随后在 Nginx 里放行隐藏目录并加缓存控制
location ^~ /.well-known/acme-challenge/ { root /var/www/letsencrypt; default_type text/plain; add_header Cache-Control "no-store" always; }
然后重新跑一次签发并看失败原因
certbot renew --dry-run --debug-challenges -v
末了改完规则清一次该前缀的缓存
curl -X PURGE https://www.example.com/.well-known/acme-challenge/test
排查用的命令都是临时敲的,没有写成脚本,事后才整理。
别只看报错消失,验证要多做一步。dry-run 输出 Congratulations, all simulated renewals succeeded,站点证书剩余有效期回到 89 天,日志里不再出现无法验证域名。
代理模式省事但会把所有路径一起接管,验证类目录最好单独走 DNS-01,别指望每次都记得加规则。这类问题最好一次改到位,反复小改反而容易把原因搅混。
