HTTP验证续签失败主因是CDN拦截/.well-known/acme-challenge/请求或80端口不通;需临时直连服务器IP、放行80端口、关闭相关缓存与伪静态拦截,并手动重载Nginx生效证书。

宝塔面板用 HTTP 验证方式续签 Let’s Encrypt 证书失败,大概率不是证书服务本身的问题,而是验证环节被拦在了半路——CDN 和 80 端口就是两个最常“背锅”也最容易被忽略的环节。
HTTP 验证时 CDN 会拦截 /.well-known/acme-challenge/ 请求
Let’s Encrypt 在续签时会向你的域名发起一个 HTTP 请求,目标路径是 http://yourdomain.com/.well-known/acme-challenge/xxx。这个请求必须直达你服务器上的 Nginx/Apache,不能被 CDN 缓存或拦截。
常见错误现象:
- 日志里反复出现
Verify error:Invalid response from http://... - 手动 curl 测试返回 404 或 CDN 的默认页(比如 Cloudflare 的 “Attention Required” 页面)
- 域名解析显示 A 记录指向 CDN,但实际服务器 IP 并未在 CDN 后台配置为源站
实操建议:
- 续签前临时将域名 DNS 解析改为直接指向服务器真实 IP(绕过 CDN)
- 如果必须走 CDN,需在 CDN 控制台关闭该路径的缓存,并放行所有
.well-known/acme-challenge/请求(Cloudflare 要关“Always Use HTTPS”和“Auto Minify”,阿里云 CDN 需添加 Page Rule) - 验证完成后可立即切回 CDN,不影响证书生效
80 端口不通或被占用导致验证请求直接超时
HTTP 验证强制要求 80 端口可访问且能响应 ACME 挑战文件。哪怕你网站只跑 HTTPS(443),Let’s Encrypt 仍会走 80 端口发起验证请求。
常见错误现象:
-
Connection refused或Timeout during connect出现在acme_v2.py日志中 - 本地执行
curl -I http://yourdomain.com/.well-known/acme-challenge/test返回空或 connection reset - 服务器上
netstat -tuln | grep :80显示端口未监听,或被其他进程(如 docker、另一个 Nginx 实例)占着
实操建议:
- 确认 Nginx 正在运行:
systemctl status nginx,并检查其配置是否监听 80 端口(listen 80;不能注释掉) - 检查防火墙:
bt 8(宝塔命令)或ufw status,确保 80 端口放行;云服务器还要检查安全组规则 - 避免伪静态规则误拦截:检查站点配置里是否有类似
location ^~ /.well-known/ { deny all; }的语句,删掉或改成allow all;
为什么“续签成功”日志却没更新证书?
宝塔的 acme_v2.py --renew=1 脚本即使拿到新证书,也不会自动重载 Nginx 配置——它只负责生成和保存证书文件(路径如 /www/server/panel/vhost/cert/yourdomain.com/),不触发 nginx -s reload。
这就导致一个典型假象:计划任务日志显示 |- 续签成功,但浏览器仍提示证书过期。
实操建议:
- 手动续签后,立刻执行
bt 1(重启 Nginx)或nginx -s reload - 更稳妥的做法是把重载命令追加到计划任务脚本末尾:
/www/server/panel/pyenv/bin/python -u /www/server/panel/class/acme_v2.py --renew=1 && nginx -s reload
- 注意:不要用
systemctl restart nginx,可能中断已有连接;nginx -s reload是平滑重载,更安全
CDN 和 80 端口看似是外围配置,但在 HTTP 验证链路上它们是刚性依赖。绕开 CDN 直连 + 确保 80 端口干净响应,能解决八成以上的“静默失败”问题。剩下两成,往往卡在证书文件没重载或 acme_v2.py 路径被面板升级改掉了。

















