证书签发和续期
Timeout during connect:Certbot 验证超时的排查与修复
Type: connection Detail: 203.0.113.10: Fetching http://example.com/.well-known/acme-challenge/...: Timeout during connect (likely firewall problem)Timeout during connect (likely firewall problem) 的意思是:Let's Encrypt 想连你服务器的 80 端口去取 HTTP-01 验证文件,始终没能建立 TCP 连接。 中间有东西把流量丢了:防火墙、云安全组、运营商封端口、地域屏蔽,或者 DNS 记录指向了别的机器。
快速修复
超时说明外部连不上你的 80 端口。从你网络之外的机器(比如手机流量热点、另一台云服务器)检查 Let's Encrypt 会检查的三件事:
dig +short A example.com
dig +short AAAA example.com
curl -4 -v -m 10 http://example.com/.well-known/acme-challenge/test
curl -6 -v -m 10 http://example.com/.well-known/acme-challenge/test
- 所有 A 和 AAAA 记录都必须指向这台服务器,残留的旧记录删掉或改正。
- 两个
curl都必须能连上(返回 404 没关系,超时不行)。 - 然后用
sudo certbot renew --dry-run或certbot certonly --dry-run -d example.com安全地重试。
原因
最常见的原因是防火墙或云安全组没放行 80 端口,其次是残留的 AAAA 记录和指向别处的 DNS。
1. 防火墙或安全组没放行 80 端口
国内云服务器最常见的原因。
- 确认: 从外部
curl -4 http://example.com/超时;服务器上sudo ss -ltnp | grep ':80 '能看到 Nginx 或 Apache 在监听。 - 修复: 每一层都放行 TCP 80:先是阿里云/腾讯云的安全组(轻量应用服务器在“防火墙”页),再是系统防火墙,宝塔用户还要在面板“安全”页放行:
sudo ufw allow 80/tcp # Ubuntu
sudo firewall-cmd --permanent --add-service=http && sudo firewall-cmd --reload # CentOS/Rocky
2. AAAA(IPv6)记录错误或残留
只要存在 AAAA 记录,Let's Encrypt 就会走 IPv6 连接。旧主机留下的 AAAA 记录,或者服务器没监听 IPv6,都会导致超时,哪怕 IPv4 一切正常。
- 确认:
curl -6超时而curl -4正常;报错详情里是 IPv6 地址。 - 修复: 删掉 AAAA 记录;或者让服务器监听 IPv6(Nginx 写
listen [::]:80;),并在安全组和防火墙里放行 IPv6 的 80 端口。
3. DNS 指向了别的机器
A 记录可能还指向旧服务器、CDN,或者不转发 80 端口的负载均衡。
- 确认: 报错详情里的 IP 不是你的服务器。
- 修复: 改 DNS,或者在流量实际到达的服务器上运行 Certbot。用了 CDN(阿里云 CDN、腾讯云 CDN 等)时,确认它把
/.well-known/acme-challenge/的 HTTP 请求回源到你的服务器。
4. 地域屏蔽、IP 白名单、fail2ban 或 WAF
Let's Encrypt 同时从多个网络位置验证,且不公布验证 IP。宝塔的“禁止海外访问”、云 WAF 的地域封禁、只放行固定 IP 的规则,都会让部分或全部验证超时。
- 确认: 防火墙或 WAF 日志里,在申请的时间点有来自陌生境外 IP 的丢弃记录。
- 修复: 对 80 端口上的
/.well-known/acme-challenge/豁免地域和 IP 规则,或者改用 DNS-01。
5. 运营商封了入站 80 端口
国内家庭宽带普遍封了入站 80 端口,在家里的 NAS、软路由上申请证书常遇到这个问题。
- 修复: 用 DNS-01(
certbot certonly --manual --preferred-challenges dns,或者对应 DNS 服务商的插件;acme.sh 自带 DNSPod、阿里云解析接口),或者用支持 TLS-ALPN-01 的客户端。
各环境修法
不管哪种环境,目标都是让公网能从 80 端口连到应答验证的服务;80 端口开不了就改用 DNS-01。
阿里云 / 腾讯云 / 华为云: 在实例绑定的安全组里添加入方向规则,TCP 80,来源 0.0.0.0/0(IPv6 用 ::/0)。光改系统防火墙不够。
宝塔面板: 面板“安全”里放行 80 端口;如果装了宝塔防火墙插件或开了“禁止海外访问”,申请期间对验证路径放行。
Docker: 负责应答验证的容器要发布 80 端口(-p 80:80),并确认没有别的容器占用。
standalone 模式: certbot certonly --standalone 需要 80 端口空闲,要先停掉 Web 服务;更推荐用 --webroot 配合正在运行的服务器。
Kubernetes(cert-manager): Ingress 控制器的 Service 必须对公网开放 80 端口,见 cert-manager 证书一直不 Ready。
完全没有入站访问: 用 DNS-01 验证,配合 DNS 服务商的插件或 API。
不要这样做
循环重试、关防火墙、照搬 IP 白名单都解决不了连通问题,还会触发限制或扩大暴露面。
- 用 cron 循环重试。 每次失败都计入每小时 5 次验证失败的限制,长期失败还可能导致签发被暂停,见 Let's Encrypt 速率限制。
- 为了签证书把整个防火墙关掉。 只放行 TCP 80 就够了,80 端口可以只做跳转到 HTTPS。
- 照搬论坛里的“Let's Encrypt IP 列表”加白名单。 官方不公布这些地址,而且会变。
常见问题
网站 HTTPS 是好的,为什么还要开 80 端口?
HTTP-01 验证规定从 80 端口开始。Let's Encrypt 可以跟随跳转(包括跳到 HTTPS),但第一步必须能连上 80。开不了 80 就用 DNS-01,或者支持的客户端用 TLS-ALPN-01。
能只给 Let's Encrypt 的 IP 开白名单吗?
不行。Let's Encrypt 从多个地点验证,也不公布固定的验证 IP,地址随时会变。要么对所有人开放 80 端口(只做跳转到 HTTPS 即可),要么用 DNS-01。
国内服务器开了“禁止海外访问”,还能用 HTTP-01 吗?
基本不能。Let's Encrypt 的验证请求来自境外多个地点,被屏蔽后就会超时。可以临时关闭该规则、对 /.well-known/acme-challenge/ 路径放行,或者直接改用 DNS-01,通过 DNSPod、阿里云解析的 API 自动验证。
可以重试几次?
每次失败都计入“每账户每标识符每小时最多 5 次验证失败”的限制。先用 --dry-run 或 --staging 调通,再正式申请。
它和 Connection refused 有什么区别?
Connection refused 表示主机有回应,但 80 端口没有程序在监听;Timeout during connect 表示完全没有回应,通常是防火墙静默丢包,或者 DNS 记录指向了错误的地址。