适用范围:阿里云 ECS 主机已备案,域名解析正常,但 Certbot 在执行 HTTP-01 验证时仍返回 403 Forbidden。
目标:在保持现有架构不变的前提下,成功签发一张同时覆盖多个子域名的 Let’s Encrypt 证书。
说明:文中域名均为示例(如 example.comsub1.example.com 等),与真实业务无关。


一、问题现象

执行命令:

certbot certonly --standalone \
  -d example.com -d www.example.com -d sub1.example.com -d sub2.example.com \
  --agree-tos -m user@example.com --cert-name example.com

输出提示:

Domain: example.com
Type: unauthorized
Detail: 203.0.113.10: Invalid response from http://example.com/.well-known/acme-challenge/xxx: 403

人工测试:

curl -I http://example.com/.well-known/acme-challenge/test

结果:

HTTP/1.1 403 Forbidden
Server: Beaver
Cache-Control: no-cache
Content-Type: text/html
Content-Length: 640
Connection: close

二、原因分析

1. “Server: Beaver” 的含义

  • “Beaver” 是阿里云 HTTP 网关的返回头。
  • 当流量未被 ECS 上的服务进程处理、而是被阿里云入口层接管时,就会出现这一标识。
  • 触发原因可能包括:
    • 请求被 WAF 或 安全代理层 拦截;
    • HTTP 访问被平台策略或端口策略过滤;
    • 请求路径或 Header 异常(例如 .well-known/acme-challenge 被安全规则误判)。

2. 与备案无直接关系

  • 即使域名已经完成工信部备案,只要触发了阿里云入口的安全规则或访问策略,也可能收到 Beaver 403;
  • 因此需从访问链路和验证方式两方面排查。

三、验证思路

  1. 确认 80 端口可直连 ECS: sudo ss -tlnp | grep ':80 ' curl -I http://<ECS公网IP>/ 若 IP 访问无返回或被防火墙拒绝,则说明 ECS 未监听 80 端口或端口策略阻断。
  2. 测试带 Host 头访问:curl -I -H 'Host: example.com' http://<ECS公网IP>/
    • 若此命令仍返回 “Server: Beaver”,说明请求在进入 ECS 前即被网关拦截;
    • 若能看到自建 Nginx/Apache 响应头,则表示可直接落地。
  3. 确认无外层安全策略干扰
    • 检查阿里云控制台 > 安全组 > 入方向规则,确保 TCP 80 端口对 0.0.0.0/0 开放;
    • 若使用了 WAF 或负载均衡,需在其规则中放行 /.well-known/acme-challenge/ 路径。

四、解决方案(按稳定性排序)

方案是否改动架构是否依赖 80 端口难度特点
A. DNS-01 手动 TXT❌ 否❌ 否★☆☆最安全稳妥,适用于所有环境
B. DNS-01 自动化(AliDNS API)❌ 否❌ 否★★☆可定时自动续签
C. HTTP-01 验证(迁移到境外服务器)✅ 是✅ 是★★☆临时解析到境外 VPS 执行验证
D. 修正规则后继续 HTTP-01✅ 是✅ 是★★★需明确入口规则及 WAF 配置

五、推荐实践:DNS-01 手动 TXT 模式

1. 执行命令

sudo certbot certonly --manual --preferred-challenges dns \
  -d example.com -d www.example.com -d sub1.example.com -d sub2.example.com \
  --agree-tos -m user@example.com --cert-name example.com

Certbot 会依次提示添加 TXT 记录,例如:

Please deploy a DNS TXT record under the name:
_acme-challenge.sub1.example.com.
with the following value:
RANDOM_TOKEN_123456

2. 在阿里云 DNS 控制台添加 TXT 记录

字段内容说明
记录类型TXT必须选择 TXT
主机记录_acme-challenge.sub1对应提示中的子域
记录值RANDOM_TOKEN_123456原样粘贴
TTL600默认即可

保留所有之前的 TXT 记录,直到 Certbot 全部验证完成。

3. 验证生效

dig TXT _acme-challenge.sub1.example.com +short

若能返回 Token 值,即可在 Certbot 窗口回车继续。

4. 完成签发

当所有域名验证通过后,输出如下:

Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/example.com/privkey.pem

这些文件即为正式证书,可直接配置在 Nginx 或 Apache 中。


六、一次性覆盖所有子域的通配符方式

若希望减少交互次数,可使用通配符(Wildcard):

sudo certbot certonly --manual --preferred-challenges dns \
  -d example.com -d '*.example.com' \
  --agree-tos -m user@example.com --cert-name example.com

此时只需在 DNS 中为 _acme-challenge.example.com 添加两条 TXT 记录,即可覆盖所有当前与未来子域名。


七、关于续签

  • 手动模式下 不会自动续签
  • 证书有效期 90 天,可在到期前重复同一命令与 TXT 步骤;
  • 若需无人值守续签,可安装 certbot-dns-aliyun 插件,并在 crontab 或 systemd timer 中执行: certbot renew

八、结论

  • 问题根源:HTTP 请求被阿里云入口层拦截(返回 Server: Beaver),非 Certbot 或防火墙配置错误。
  • 验证方式选择:DNS-01 绕过所有 HTTP 链路验证,是最稳妥的方案。
  • 长期策略
    • 若不依赖阿里云 WAF ,可在安全组和 Nginx 层放行 .well-known/acme-challenge
    • 若追求自动化,采用 AliDNS API 插件实现自动续签。

命令速览

# 多域名证书(手动 DNS)
certbot certonly --manual --preferred-challenges dns \
  -d example.com -d www.example.com -d sub1.example.com -d sub2.example.com \
  --agree-tos -m user@example.com --cert-name example.com

# 通配符 + 根域
certbot certonly --manual --preferred-challenges dns \
  -d example.com -d '*.example.com' \
  --agree-tos -m user@example.com --cert-name example.com

# 查看证书状态
certbot certificates

总结
即便域名已备案,阿里云的 HTTP 安全网关仍可能对某些路径或验证请求返回 403 (Beaver)。通过切换到 DNS-01 验证方式,可以彻底绕开入口层限制,顺利获得包含多个子域名的 Let’s Encrypt 证书。

Leave a Reply

Your email address will not be published. Required fields are marked *