首次配置SSL证书异常:已生成acme.json但Traefik无法完成TLS-ALPN-01挑战
看起来你遇到了Traefik对接Let's Encrypt时的典型坑——虽然磁盘上已经生成了acme.json文件,但挑战始终失败,报错无法协商acme-tls/1协议。结合你用Cloudflare做DNS/CDN的场景,我来帮你一步步拆解问题、排查验证:
先澄清:acme.json存在≠拿到有效证书
你看到的acme.json大概率只是Traefik创建的空文件或者包含失败的挑战记录,并不是真正持有生效的SSL证书。你可以用这条命令验证:
cat ./volumes/traefik/acme/acme.json | jq
如果输出里的"certificates"数组是空的,或者状态显示"invalid",说明确实没拿到可用的证书。
核心问题:Cloudflare代理阻断了TLS-ALPN-01挑战
TLS-ALPN-01挑战的工作逻辑是:Let's Encrypt的服务器直接向你的域名443端口发起请求,要求协商acme-tls/1协议,Traefik需要直接响应这个请求才能完成验证。
但你用了Cloudflare的CDN代理(DNS记录上的橙色云朵),此时所有外部请求都会先到Cloudflare的节点,再转发到你的服务器。Cloudflare本身不支持acme-tls/1协议协商,所以这个挑战必然失败。
解决方案:三种可选路径
1. 临时关闭Cloudflare代理(最快验证)
把Cloudflare DNS记录里的橙色云朵改成灰色(暂停代理),然后重启Traefik:
sudo docker-compose down && sudo docker-compose up -d
等几分钟后查看Traefik日志,如果挑战成功,再把Cloudflare代理重新打开即可。
2. 改用HTTP-01挑战(适合保持Cloudflare代理)
HTTP-01挑战通过80端口完成,Cloudflare代理下可以正常工作。修改Traefik的command配置:
command: - --providers.docker=true - --providers.docker.exposedbydefault=false - --entrypoints.web.address=:80 - --entrypoints.websecure.address=:443 - --certificatesresolvers.letsencrypt.acme.email=tgmjackcroc@gmail.com - --certificatesresolvers.letsencrypt.acme.storage=acme/acme.json # 替换成HTTP挑战 - --certificatesresolvers.letsencrypt.acme.httpchallenge=true - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web - --entryPoints.web.http.redirections.entryPoint.to=websecure - --entryPoints.web.http.redirections.entryPoint.scheme=https - --entryPoints.web.http.redirections.entrypoint.permanent=true - --certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
重启Traefik后,挑战会通过80端口完成,Cloudflare代理不会干扰这个流程。
3. 改用DNS-01挑战(适合无法开放80/443的场景)
如果需要一直保持Cloudflare代理,且不想开放80/443端口到源服务器,可以用DNS-01挑战。这种方式需要Traefik通过Cloudflare API自动添加DNS验证记录,配置步骤如下:
- 首先在Cloudflare获取你的API密钥(全局API密钥或限制权限的API令牌)
- 在Traefik的
command里添加DNS挑战配置:command: # 其他配置保持不变 - --certificatesresolvers.letsencrypt.acme.dnschallenge=true - --certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare - 添加Cloudflare环境变量到Traefik服务:
environment: - CLOUDFLARE_EMAIL=你的Cloudflare邮箱 - CLOUDFLARE_API_KEY=你的Cloudflare API密钥 - 重启Traefik即可自动完成DNS验证。
额外排查与注意事项
- 检查端口开放情况:确保服务器的安全组/防火墙已经开放80、443端口,允许所有外部IP访问。
- 切换到生产环境CA:你现在用的是Let's Encrypt的测试环境(staging),测试成功后可以把
caserver改成生产环境地址:https://acme-v02.api.letsencrypt.org/directory,这样拿到的证书会被浏览器信任。 - 修复acme.json权限:Traefik需要
acme.json的权限为600,否则可能无法写入证书。运行这条命令修正:chmod 600 ./volumes/traefik/acme/acme.json
备注:内容来源于stack exchange,提问作者tgmjack

