DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

Caddy 按需 TLS 报 non-2xx status code 403,先查 ask 请求

新域名TLS握手因ask端点403被拒绝,核对服务实际GET、domain参数与授权端点路径,保留域名准入。

新域名访问 HTTPS 时握手失败,Caddy 日志同时出现 certificate for hostname ... not allowed 和 non-2xx status code 403,应先检查按需 TLS 的授权请求。这里的 403 来自 ask 端点,不是访客已经进入网站后收到的业务响应。

授权端点拒绝后,Caddy 不会为这个请求继续取得所需证书。此时重签主站证书或调整应用页面,通常没有触及失败的环节。固定域名 HTTPS 正常,也不能证明新域名的按需授权正常。

确认报错对应哪个授权 URL 和域名

核对实际加载的全局 on_demand_tls 配置,以及需要按需处理的站点是否启用了 tls 下的 on_demand。全局授权配置本身不会替所有站点开启按需 TLS。

在受控诊断期间启用全局 debug,按一次新域名握手的时间查找授权 URL、域名和返回状态,再关联授权应用、前置代理或 CDN 的请求日志。启用时间应尽量短,日志私有保存;不要把配置环境、令牌或内部地址完整公开。

如果应用没有收到请求,而前置代理有 403,应先检查拦截发生在哪一层。应用没有日志也可能是日志记录范围不足,不能单独证明 Caddy 发错了 Host 或 CDN 一定出了故障。

手动请求 200,需要与 Caddy 的请求条件对照

ask 会发起 GET,并增加 domain 查询参数。以下示例只用于从 Caddy 实际运行环境检查已授权域名,URL 与域名需替换成自己的值:

curl --verbose --get \
  --data-urlencode 'domain=customer.example.net' \
  'https://domains.example.com/verify'

不要加 -L 把重定向后的 200 当成原端点成功,也不要用 -k 掩盖授权端点的证书错误。Caddy 2.11.7 的 HTTP permission 实现不跟随重定向,HTTP 客户端总超时为 10 秒;实际旧版本或自定义 permission 模块还需核对自己的行为。

手动 curl 的 200 也只是对照结果。电脑与服务容器可能使用不同 DNS、代理、网络出口和信任配置;手动请求还可能携带不同 Cookie 或头字段。应关联 Caddy 发出的那次实际请求,而不是假设两者完全相同。

当前 HTTP permission 接受 200–299,其余状态会拒绝。端点不应依赖浏览器登录、交互式挑战或跳转才能返回授权结果。若已有 URL 含查询参数,确认应用收到的 domain 与日志一致,不要自己拼接一条未编码的参数串替代实际行为。

修复授权路径,保留域名准入

检查端点所在站点、路径匹配、WAF 或访问规则,确认服务请求能够到达真正的授权应用。若采用专用内部端点或独立验证域名,应根据现有网络架构配置可达性、TLS 和访问限制,不能直接把整个业务站点从 CDN 移除。

授权应用仍需查询该域名是否已经完成注册和必要验证,快速返回明确状态。不能为消除 403 对所有域名统一返回 200,也不要删除 permission 检查;这样会改变证书签发的准入边界。

修正前保存 Caddy 配置、端点地址和相关访问规则。更换端点时,还要保证旧规则撤销后不会留下无保护的授权接口。

分别验证允许、拒绝与签发

用一个获授权、尚需取得证书的域名确认真实授权请求到达应用、返回允许,再检查后续证书流程与 HTTPS 访问。授权通过不等于 CA 签发必然成功;之后的 DNS、挑战可达性或签发限额错误应按新日志处理。

再用一个明确不在准入范围的受控域名验证拒绝仍生效。不要只测试已经在内存中可直接服务的证书,因为这未必触发所要检查的授权路径。

若授权应用不可达或返回错误,保留具体失败层次。一次改用另一个验证域名后成功,可以支持继续检查原路径,却不足以认定所有 Cloudflare 代理都会导致 ask 失败。