acme http-01验证必须走80端口,因其协议硬性规定ca须通过明文http访问http://域名/.well-known/acme-challenge/xxx完成验证,不支持自定义端口;80端口还需常驻以保障续期和http跳转。

为什么 ACME HTTP-01 验证必须走 80 端口
Let’s Encrypt 的 HTTP-01 挑战要求证书颁发机构(CA)能从公网直接访问 http://yourdomain.com/.well-known/acme-challenge/xxx 这个路径。FrankenPHP 自身不处理 ACME,但底层 Caddy 在启用自动 HTTPS 时会自动监听 :80 并托管该路径——不是为了提供网站服务,而是专供 CA 验证用。
常见错误现象:acme: Error 403 urn:ietf:params:acme:error:unauthorized 或 Caddy 日志里反复出现 HTTP request to acme-v02.api.letsencrypt.org failed,往往是因为 80 端口没放行、被防火墙拦截,或反向代理(如 Nginx)未透传该路径。
- 阿里云/腾讯云安全组必须放行
80/TCP入方向,且不能只开给 CDN IP——CA 服务器的 IP 是动态的 - 若你用 frp 或其他内网穿透,需确保中转端口(如
7000)映射到了宿主机的80,而非 FrankenPHP 容器内的任意端口 - Caddyfile 中不能删掉
:80监听块:即使你只想要 HTTPS,Caddy 也必须保留这个 HTTP 入口来响应挑战;否则会卡在Waiting for verification...
Caddy 的自动 HTTPS 流程如何依赖 80 端口
Caddy 默认开启 automatic_https,它会在检测到域名配置(如 example.com)后,自动做三件事:监听 :80 响应 ACME 挑战、监听 :443 提供 HTTPS 服务、对所有 :80 请求 301 跳转到 :443。这三者是原子行为,无法拆开禁用其中一项而不破坏流程。
容易踩的坑:SERVER_NAME=example.com 会触发整套自动 HTTPS,哪怕你没配证书;而 SERVER_NAME=:80 则彻底绕过该机制——它让 Caddy 放弃域名匹配,只起一个纯 HTTP server,不再尝试申请证书。
- 别在 Caddyfile 里手动写
redir https://{host}{uri}同时又保留域名块,否则和自动跳转叠加,导致ERR_TOO_MANY_REDIRECTS - 如果用 CDN,CDN 必须把
/.well-known/acme-challenge/路径直通回源(不缓存、不改写),否则 Caddy 根本收不到验证请求 - 本地调试时,
curl -v http://localhost/.well-known/acme-challenge/test应返回 404(路径存在但文件不存在),而不是连接拒绝或超时——这是验证 80 端口通路是否正常的最快方式
80 端口被占用了,还能走自动 HTTPS 吗
不能。ACME HTTP-01 协议硬性规定验证必须走明文 HTTP + 80 端口,不支持自定义端口。如果你的 80 被 IIS、Nginx 或系统服务(PID=4)占用,Caddy 就无法绑定,自动 HTTPS 会直接失败,日志里会出现 listen tcp :80: bind: address already in use。
实操建议优先级:先停用冲突服务,再考虑变通方案。FrankenPHP 不支持把 ACME 验证换到其他端口,也没有 “DNS-01 回退” 开关。
- Windows 下查 PID=4 占用:管理员运行
netstat -ano | findstr :80,确认后执行sc stop w3svc(禁用 World Wide Web Publishing Service) - Linux 下常用
sudo lsof -i :80或sudo ss -tulpn | grep :80找进程,再kill -9终止 - 实在无法释放 80,只能放弃 HTTP-01,改用 DNS-01(需手动配置 API 密钥)或干脆不用自动 HTTPS,改用已有证书文件 + 显式
tls /path/to/cert.pem /path/to/key.pem
HTTPS 已生效,为什么还要开着 80 端口
80 端口在证书签发完成后仍需常驻,原因有两个:一是持续响应后续的证书续期挑战(Let’s Encrypt 每 60 天续一次),二是承担用户输入 http:// 时的协议跳转。一旦关掉,下次续期失败,证书过期,且用户首次访问会直接报连接失败而非跳转。
最容易被忽略的一点:很多人以为“HTTPS 有了,80 就可以关了”,结果两周后发现网站打不开,查日志才发现续期失败,而 Caddy 默认不会发告警邮件——它只会默默重试,直到失败三次后停用该域名。
- 生产环境不要为“省一个端口”去关 80;安全组里保持
80/TCP入方向开放,但可限制来源(如只允 Let’s Encrypt 的 ASN 或 CDN IP 段) - 若你用 Caddyfile 自定义了
:80块,务必只留redir或handle,别加php_server或其他处理器——那会干扰 ACME 验证路径的静态响应 - 检查 Caddy 日志关键词:
acme_client(成功续期)、revoke(证书被撤回)、timeout(验证超时)——这些比网站是否能打开更能提前暴露问题
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











